diff --git a/.gitmodules b/.gitmodules
index 1e1d0f7c0..5807a21e6 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -25,12 +25,14 @@
[submodule "submodules/externals/x264"]
path = submodules/externals/x264
url = git://git.videolan.org/x264.git
+ ignore = dirty
[submodule "submodules/msx264"]
path = submodules/msx264
url = git://git.linphone.org/msx264.git
[submodule "submodules/externals/libvpx"]
path = submodules/externals/libvpx
url = http://git.chromium.org/webm/libvpx.git
+ ignore = dirty
[submodule "submodules/bzrtp"]
path = submodules/bzrtp
url = git://git.linphone.org/bzrtp.git
@@ -55,15 +57,18 @@
[submodule "submodules/externals/opus"]
path = submodules/externals/opus
url = git://git.opus-codec.org/opus.git
+ ignore = dirty
[submodule "submodules/externals/libxml2"]
path = submodules/externals/libxml2
url = git://git.gnome.org/libxml2
+ ignore = dirty
[submodule "submodules/cunit"]
path = submodules/cunit
url = git://git.linphone.org/cunit.git
[submodule "submodules/externals/openh264"]
path = submodules/externals/openh264
url = https://github.com/cisco/openh264
+ ignore = dirty
[submodule "submodules/msopenh264"]
path = submodules/msopenh264
url = git://git.linphone.org/msopenh264.git
diff --git a/Classes/Base.lproj/ChatViewController.xib b/Classes/Base.lproj/ChatViewController.xib
index 878b38caf..4f30247c4 100644
--- a/Classes/Base.lproj/ChatViewController.xib
+++ b/Classes/Base.lproj/ChatViewController.xib
@@ -1,8 +1,7 @@
-
+
-
-
+
@@ -91,14 +90,11 @@
+
+
-
-
-
-
-
@@ -113,4 +109,9 @@
-
\ No newline at end of file
+
+
+
+
+
+
diff --git a/Classes/Base.lproj/ContactsViewController.xib b/Classes/Base.lproj/ContactsViewController.xib
index d16430f4d..ab36f8c0b 100644
--- a/Classes/Base.lproj/ContactsViewController.xib
+++ b/Classes/Base.lproj/ContactsViewController.xib
@@ -1,8 +1,8 @@
-
+
-
-
+
+
@@ -11,6 +11,7 @@
+
@@ -21,7 +22,7 @@
-
+
@@ -109,11 +110,21 @@
+
+
+
+
+
+
+
+
+
+
@@ -127,4 +138,9 @@
-
\ No newline at end of file
+
+
+
+
+
+
diff --git a/Classes/Base.lproj/DialerViewController.xib b/Classes/Base.lproj/DialerViewController.xib
index 51f2e90aa..bc4528347 100644
--- a/Classes/Base.lproj/DialerViewController.xib
+++ b/Classes/Base.lproj/DialerViewController.xib
@@ -1,8 +1,8 @@
-
+
-
-
+
+
@@ -63,7 +63,7 @@
-
+
+
@@ -363,4 +365,9 @@
-
\ No newline at end of file
+
+
+
+
+
+
diff --git a/Classes/Base.lproj/DialerViewController~ipad.xib b/Classes/Base.lproj/DialerViewController~ipad.xib
index d9bb2c508..63f48482e 100644
--- a/Classes/Base.lproj/DialerViewController~ipad.xib
+++ b/Classes/Base.lproj/DialerViewController~ipad.xib
@@ -1,8 +1,8 @@
-
+
-
+
@@ -111,7 +111,7 @@
-
+
@@ -242,7 +242,7 @@
-
+
@@ -350,6 +350,8 @@
+
+
@@ -401,4 +403,9 @@
+
+
+
+
+
diff --git a/Classes/ChatRoomTableViewController.m b/Classes/ChatRoomTableViewController.m
index 323c6943a..e1995274b 100644
--- a/Classes/ChatRoomTableViewController.m
+++ b/Classes/ChatRoomTableViewController.m
@@ -73,7 +73,7 @@
- (void)addChatEntry:(LinphoneChatMessage*)chat {
- messageList = ms_list_append(messageList, chat);
+ messageList = ms_list_append(messageList, linphone_chat_message_ref(chat));
int pos = ms_list_size(messageList) - 1;
[self.tableView beginUpdates];
diff --git a/Classes/ChatRoomViewController.m b/Classes/ChatRoomViewController.m
index cdfc82e09..36c5247c1 100644
--- a/Classes/ChatRoomViewController.m
+++ b/Classes/ChatRoomViewController.m
@@ -333,7 +333,7 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta
[LinphoneManager setValueInMessageAppData:[internalUrl absoluteString] forKey:@"localimage" inMessage:msg];
}
- [tableController addChatEntry:linphone_chat_message_ref(msg)];
+ [tableController addChatEntry:msg];
[tableController scrollToBottom:true];
return TRUE;
}
@@ -790,12 +790,13 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta
[UIView setAnimationCurve:curve];
[UIView setAnimationBeginsFromCurrentState:TRUE];
- if(UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) {
+ if(([[UIDevice currentDevice].systemVersion floatValue] < 8) &&
+ UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) {
int width = endFrame.size.height;
endFrame.size.height = endFrame.size.width;
endFrame.size.width = width;
}
-
+
// Resize chat view
{
CGRect viewFrame = [[self view] frame];
diff --git a/Classes/ChatViewController.m b/Classes/ChatViewController.m
index 73e3878bd..aab106dbb 100644
--- a/Classes/ChatViewController.m
+++ b/Classes/ChatViewController.m
@@ -110,11 +110,22 @@ static UICompositeViewDescription *compositeDescription = nil;
-(void) startChatRoom {
//Push ChatRoom
+ LinphoneChatRoom* room = linphone_core_get_or_create_chat_room([LinphoneManager getLc], [addressField.text UTF8String]);
+ if( room != nil ){
ChatRoomViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ChatRoomViewController compositeViewDescription] push:TRUE], ChatRoomViewController);
if(controller != nil) {
LinphoneChatRoom* room = linphone_core_get_or_create_chat_room([LinphoneManager getLc], [addressField.text UTF8String]);
[controller setChatRoom:room];
}
+ } else {
+ UIAlertView* alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Invalid address", nil)
+ message:@"Please specify the entire SIP address for the chat"
+ delegate:nil
+ cancelButtonTitle:NSLocalizedString(@"Cancel", nil)
+ otherButtonTitles:nil];
+ [alert show];
+ [alert release];
+ }
addressField.text = @"";
}
@@ -123,7 +134,8 @@ static UICompositeViewDescription *compositeDescription = nil;
[ContactSelection setSelectionMode:ContactSelectionModeMessage];
[ContactSelection setAddAddress:nil];
[ContactSelection setSipFilter: [LinphoneManager instance].contactFilter];
- [ContactSelection setEmailFilter:FALSE];
+ [ContactSelection enableEmailFilter:FALSE];
+ [ContactSelection setNameOrEmailFilter:nil];
[[PhoneMainView instance] changeCurrentView:[ContactsViewController compositeViewDescription] push:TRUE];
} else {
[self startChatRoom];
diff --git a/Classes/ContactDetailsTableViewController.m b/Classes/ContactDetailsTableViewController.m
index 2556f7dd7..ee3ebf4f8 100644
--- a/Classes/ContactDetailsTableViewController.m
+++ b/Classes/ContactDetailsTableViewController.m
@@ -74,6 +74,12 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
- (void)initContactDetailsTableViewController {
dataCache = [[NSMutableArray alloc] init];
+
+ // pre-fill the data-cache with empty arrays
+ for(int i=ContactSections_Number; i< ContactSections_MAX; i++){
+ [dataCache addObject:@[]];
+ }
+
labelArray = [[NSMutableArray alloc] initWithObjects:
[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"],
[NSString stringWithString:(NSString*)kABPersonPhoneMobileLabel],
@@ -201,7 +207,8 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
if(CFStringCompare((CFStringRef)[LinphoneManager instance].contactSipField, CFDictionaryGetValue(lDict, kABPersonInstantMessageServiceKey), kCFCompareCaseInsensitive) == 0) {
add = true;
}
- } else { //check domain
+ } else {
+ //check domain
LinphoneAddress* address = linphone_address_new([(NSString*)CFDictionaryGetValue(lDict,kABPersonInstantMessageUsernameKey) UTF8String]);
if (address) {
if ([[ContactSelection getSipFilter] compare:@"*" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
diff --git a/Classes/ContactsTableViewController.m b/Classes/ContactsTableViewController.m
index 459f86e4e..c591b5dbc 100644
--- a/Classes/ContactsTableViewController.m
+++ b/Classes/ContactsTableViewController.m
@@ -4,18 +4,18 @@
*
* 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
+ * 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.
- */
+ */
#import "ContactsTableViewController.h"
#import "UIContactCell.h"
@@ -33,237 +33,273 @@ static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef inf
#pragma mark - Lifecycle Functions
- (void)initContactsTableViewController {
- addressBookMap = [[OrderedDictionary alloc] init];
- avatarMap = [[NSMutableDictionary alloc] init];
-
- addressBook = ABAddressBookCreateWithOptions(nil, nil);
-
- ABAddressBookRegisterExternalChangeCallback(addressBook, sync_address_book, self);
+ addressBookMap = [[OrderedDictionary alloc] init];
+ avatarMap = [[NSMutableDictionary alloc] init];
+
+ addressBook = ABAddressBookCreateWithOptions(nil, nil);
+
+ ABAddressBookRegisterExternalChangeCallback(addressBook, sync_address_book, self);
}
- (id)init {
- self = [super init];
- if (self) {
+ self = [super init];
+ if (self) {
[self initContactsTableViewController];
- }
- return self;
+ }
+ return self;
}
- (id)initWithCoder:(NSCoder *)decoder {
- self = [super initWithCoder:decoder];
- if (self) {
+ self = [super initWithCoder:decoder];
+ if (self) {
[self initContactsTableViewController];
}
- return self;
-}
+ return self;
+}
- (void)dealloc {
- ABAddressBookUnregisterExternalChangeCallback(addressBook, sync_address_book, self);
- CFRelease(addressBook);
- [addressBookMap release];
- [avatarMap release];
- [super dealloc];
+ ABAddressBookUnregisterExternalChangeCallback(addressBook, sync_address_book, self);
+ CFRelease(addressBook);
+ [addressBookMap release];
+ [avatarMap release];
+ [super dealloc];
}
-#pragma mark -
+#pragma mark -
+
+- (BOOL)contactHasValidSipDomain:(ABRecordRef)person {
+ // Check if one of the contact' sip URI matches the expected SIP filter
+ ABMultiValueRef personSipAddresses = ABRecordCopyValue(person, kABPersonInstantMessageProperty);
+ BOOL match = false;
+ NSString * filter = [ContactSelection getSipFilter];
+
+ for(int i = 0; i < ABMultiValueGetCount(personSipAddresses) && !match; ++i) {
+ CFDictionaryRef lDict = ABMultiValueCopyValueAtIndex(personSipAddresses, i);
+ if(CFDictionaryContainsKey(lDict, kABPersonInstantMessageServiceKey)) {
+ CFStringRef serviceKey = CFDictionaryGetValue(lDict, kABPersonInstantMessageServiceKey);
+
+ if (CFStringCompare((CFStringRef)[LinphoneManager instance].contactSipField, serviceKey, kCFCompareCaseInsensitive) == 0) {
+ match = true;
+ }
+ } else {
+ //check domain
+ LinphoneAddress* address = linphone_address_new([(NSString*)CFDictionaryGetValue(lDict,kABPersonInstantMessageUsernameKey) UTF8String]);
+
+ if (address) {
+ NSString* domain = [NSString stringWithCString:linphone_address_get_domain(address)
+ encoding:[NSString defaultCStringEncoding]];
+
+ if (([filter compare:@"*" options:NSCaseInsensitiveSearch] == NSOrderedSame)
+ || ([filter compare:domain options:NSCaseInsensitiveSearch] == NSOrderedSame)) {
+ match = true;
+ }
+ linphone_address_destroy(address);
+ }
+ }
+ CFRelease(lDict);
+ }
+ return match;
+}
+
+static int ms_strcmpfuz(const char * fuzzy_word, const char * sentence) {
+ if (! fuzzy_word || !sentence) {
+ return fuzzy_word == sentence;
+ }
+ const char * c = fuzzy_word;
+ const char * within_sentence = sentence;
+ for (; c != NULL && *c != '\0' && within_sentence != NULL; ++c) {
+ within_sentence = strchr(within_sentence, *c);
+ // Could not find c character in sentence. Abort.
+ if (within_sentence == NULL) {
+ break;
+ }
+ // since strchr returns the index of the matched char, move forward
+ within_sentence++;
+ }
+
+ // If the whole fuzzy was found, returns 0. Otherwise returns number of characters left.
+ return (within_sentence != NULL ? 0 : fuzzy_word + strlen(fuzzy_word) - c);
+}
- (void)loadData {
- [LinphoneLogger logc:LinphoneLoggerLog format:"Load contact list"];
- @synchronized (addressBookMap) {
-
- // Reset Address book
- [addressBookMap removeAllObjects];
-
- NSArray *lContacts = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
- for (id lPerson in lContacts) {
- BOOL add = true;
- if([ContactSelection getSipFilter] || [ContactSelection getEmailFilter]) {
- add = false;
- }
- if([ContactSelection getSipFilter]) {
- ABMultiValueRef lMap = ABRecordCopyValue((ABRecordRef)lPerson, kABPersonInstantMessageProperty);
- for(int i = 0; i < ABMultiValueGetCount(lMap); ++i) {
- CFDictionaryRef lDict = ABMultiValueCopyValueAtIndex(lMap, i);
- if(CFDictionaryContainsKey(lDict, kABPersonInstantMessageServiceKey)) {
- CFStringRef serviceKey = CFDictionaryGetValue(lDict, kABPersonInstantMessageServiceKey);
- CFStringRef username = username=CFDictionaryGetValue(lDict, kABPersonInstantMessageUsernameKey);
- if(CFStringCompare((CFStringRef)[LinphoneManager instance].contactSipField, serviceKey, kCFCompareCaseInsensitive) == 0) {
- add = true;
- } else {
- add=false;
+ [LinphoneLogger logc:LinphoneLoggerLog format:"Load contact list"];
+ @synchronized (addressBookMap) {
+
+ // Reset Address book
+ [addressBookMap removeAllObjects];
+
+ NSArray *lContacts = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
+ for (id lPerson in lContacts) {
+ BOOL add = true;
+ ABRecordRef person = (ABRecordRef)lPerson;
+
+ // Do not add the contact directly if we set some filter
+ if([ContactSelection getSipFilter] || [ContactSelection emailFilterEnabled]) {
+ add = false;
+ }
+ if([ContactSelection getSipFilter] && [self contactHasValidSipDomain:person]) {
+ add = true;
+ }
+ if (!add && [ContactSelection emailFilterEnabled]) {
+ ABMultiValueRef personEmailAddresses = ABRecordCopyValue(person, kABPersonEmailProperty);
+ // Add this contact if it has an email
+ add = (ABMultiValueGetCount(personEmailAddresses) > 0);
+
+ CFRelease(personEmailAddresses);
+ }
+
+ if(add) {
+ CFStringRef lFirstName = ABRecordCopyValue(person, kABPersonFirstNameProperty);
+ CFStringRef lLocalizedFirstName = (lFirstName != nil)? ABAddressBookCopyLocalizedLabel(lFirstName): nil;
+ CFStringRef lLastName = ABRecordCopyValue(person, kABPersonLastNameProperty);
+ CFStringRef lLocalizedLastName = (lLastName != nil)? ABAddressBookCopyLocalizedLabel(lLastName): nil;
+ CFStringRef lOrganization = ABRecordCopyValue(person, kABPersonOrganizationProperty);
+ CFStringRef lLocalizedlOrganization = (lOrganization != nil)? ABAddressBookCopyLocalizedLabel(lOrganization): nil;
+ NSString *name = nil;
+ if(lLocalizedFirstName != nil && lLocalizedLastName != nil) {
+ name=[NSString stringWithFormat:@"%@ %@", [(NSString *)lLocalizedFirstName retain], [(NSString *)lLocalizedLastName retain]];
+ } else if(lLocalizedLastName != nil) {
+ name=[NSString stringWithFormat:@"%@",[(NSString *)lLocalizedLastName retain]];
+ } else if(lLocalizedFirstName != nil) {
+ name=[NSString stringWithFormat:@"%@",[(NSString *)lLocalizedFirstName retain]];
+ } else if(lLocalizedlOrganization != nil) {
+ name=[NSString stringWithFormat:@"%@",[(NSString *)lLocalizedlOrganization retain]];
+ }
+
+ if(name != nil && [name length] > 0) {
+ // Add the contact only if it fuzzy match filter too (if any)
+ if ([ContactSelection getNameOrEmailFilter] == nil ||
+ (ms_strcmpfuz([[[ContactSelection getNameOrEmailFilter] lowercaseString] UTF8String], [[name lowercaseString] UTF8String]) == 0)) {
+
+ // Put in correct subDic
+ NSString *firstChar = [[name substringToIndex:1] uppercaseString];
+ if([firstChar characterAtIndex:0] < 'A' || [firstChar characterAtIndex:0] > 'Z') {
+ firstChar = @"#";
}
- } else {
- //check domain
- LinphoneAddress* address = linphone_address_new([(NSString*)CFDictionaryGetValue(lDict,kABPersonInstantMessageUsernameKey) UTF8String]);
- if (address) {
- if ([[ContactSelection getSipFilter] compare:@"*" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
- add = true;
- } else {
- NSString* domain = [NSString stringWithCString:linphone_address_get_domain(address)
- encoding:[NSString defaultCStringEncoding]];
- add = [domain compare:[ContactSelection getSipFilter] options:NSCaseInsensitiveSearch] == NSOrderedSame;
- }
- linphone_address_destroy(address);
- } else {
- add = false;
- }
- }
- CFRelease(lDict);
- }
- CFRelease(lMap);
- }
- if ((add == false) && [ContactSelection getEmailFilter]) {
- ABMultiValueRef lMap = ABRecordCopyValue((ABRecordRef)lPerson, kABPersonEmailProperty);
- if (ABMultiValueGetCount(lMap) > 0) {
- add = true;
- }
- CFRelease(lMap);
- }
- if(add) {
- CFStringRef lFirstName = ABRecordCopyValue((ABRecordRef)lPerson, kABPersonFirstNameProperty);
- CFStringRef lLocalizedFirstName = (lFirstName != nil)? ABAddressBookCopyLocalizedLabel(lFirstName): nil;
- CFStringRef lLastName = ABRecordCopyValue((ABRecordRef)lPerson, kABPersonLastNameProperty);
- CFStringRef lLocalizedLastName = (lLastName != nil)? ABAddressBookCopyLocalizedLabel(lLastName): nil;
- CFStringRef lOrganization = ABRecordCopyValue((ABRecordRef)lPerson, kABPersonOrganizationProperty);
- CFStringRef lLocalizedlOrganization = (lOrganization != nil)? ABAddressBookCopyLocalizedLabel(lOrganization): nil;
- NSString *name = nil;
- if(lLocalizedFirstName != nil && lLocalizedLastName != nil) {
- name=[NSString stringWithFormat:@"%@%@", [(NSString *)lLocalizedFirstName retain], [(NSString *)lLocalizedLastName retain]];
- } else if(lLocalizedLastName != nil) {
- name=[NSString stringWithFormat:@"%@",[(NSString *)lLocalizedLastName retain]];
- } else if(lLocalizedFirstName != nil) {
- name=[NSString stringWithFormat:@"%@",[(NSString *)lLocalizedFirstName retain]];
- } else if(lLocalizedlOrganization != nil) {
- name=[NSString stringWithFormat:@"%@",[(NSString *)lLocalizedlOrganization retain]];
- }
- if(name != nil && [name length] > 0) {
- // Put in correct subDic
- NSString *firstChar = [[name substringToIndex:1] uppercaseString];
- if([firstChar characterAtIndex:0] < 'A' || [firstChar characterAtIndex:0] > 'Z') {
- firstChar = @"#";
- }
- OrderedDictionary *subDic =[addressBookMap objectForKey: firstChar];
- if(subDic == nil) {
- subDic = [[[OrderedDictionary alloc] init] autorelease];
- [addressBookMap insertObject:subDic forKey:firstChar selector:@selector(caseInsensitiveCompare:)];
- }
- [subDic insertObject:lPerson forKey:name selector:@selector(caseInsensitiveCompare:)];
- }
- if(lLocalizedlOrganization != nil)
- CFRelease(lLocalizedlOrganization);
- if(lOrganization != nil)
- CFRelease(lOrganization);
- if(lLocalizedLastName != nil)
- CFRelease(lLocalizedLastName);
- if(lLastName != nil)
- CFRelease(lLastName);
- if(lLocalizedFirstName != nil)
- CFRelease(lLocalizedFirstName);
- if(lFirstName != nil)
- CFRelease(lFirstName);
- }
- }
- if (lContacts) CFRelease(lContacts);
- }
- [self.tableView reloadData];
+ OrderedDictionary *subDic =[addressBookMap objectForKey: firstChar];
+ if(subDic == nil) {
+ subDic = [[[OrderedDictionary alloc] init] autorelease];
+ [addressBookMap insertObject:subDic forKey:firstChar selector:@selector(caseInsensitiveCompare:)];
+ }
+ [subDic insertObject:lPerson forKey:name selector:@selector(caseInsensitiveCompare:)];
+ }
+ }
+ if(lLocalizedlOrganization != nil)
+ CFRelease(lLocalizedlOrganization);
+ if(lOrganization != nil)
+ CFRelease(lOrganization);
+ if(lLocalizedLastName != nil)
+ CFRelease(lLocalizedLastName);
+ if(lLastName != nil)
+ CFRelease(lLastName);
+ if(lLocalizedFirstName != nil)
+ CFRelease(lLocalizedFirstName);
+ if(lFirstName != nil)
+ CFRelease(lFirstName);
+ }
+ }
+ if (lContacts)
+ CFRelease(lContacts);
+ }
+ [self.tableView reloadData];
}
static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef info, void *context) {
- ContactsTableViewController* controller = (ContactsTableViewController*)context;
- ABAddressBookRevert(addressBook);
- [controller->avatarMap removeAllObjects];
- [controller loadData];
+ ContactsTableViewController* controller = (ContactsTableViewController*)context;
+ ABAddressBookRevert(addressBook);
+ [controller->avatarMap removeAllObjects];
+ [controller loadData];
}
#pragma mark - ViewController Functions
- (void)viewWillDisappear:(BOOL)animated {
- [super viewWillDisappear:animated];
+ [super viewWillDisappear:animated];
}
#pragma mark - UITableViewDataSource Functions
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
- return [addressBookMap allKeys];
+ return [addressBookMap allKeys];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
- return [addressBookMap count];
+ return [addressBookMap count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
- return [(OrderedDictionary *)[addressBookMap objectForKey: [addressBookMap keyAtIndex: section]] count];
+ return [(OrderedDictionary *)[addressBookMap objectForKey: [addressBookMap keyAtIndex: section]] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
- static NSString *kCellId = @"UIContactCell";
- UIContactCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId];
- if (cell == nil) {
- cell = [[[UIContactCell alloc] initWithIdentifier:kCellId] autorelease];
-
- // Background View
- UACellBackgroundView *selectedBackgroundView = [[[UACellBackgroundView alloc] initWithFrame:CGRectZero] autorelease];
- cell.selectedBackgroundView = selectedBackgroundView;
- [selectedBackgroundView setBackgroundColor:LINPHONE_TABLE_CELL_BACKGROUND_COLOR];
- }
- OrderedDictionary *subDic = [addressBookMap objectForKey: [addressBookMap keyAtIndex: [indexPath section]]];
-
- NSString *key = [[subDic allKeys] objectAtIndex:[indexPath row]];
- ABRecordRef contact = [subDic objectForKey:key];
-
- // Cached avatar
- UIImage *image = nil;
- id data = [avatarMap objectForKey:[NSNumber numberWithInt: ABRecordGetRecordID(contact)]];
- if(data == nil) {
- image = [FastAddressBook getContactImage:contact thumbnail:true];
- if(image != nil) {
- [avatarMap setObject:image forKey:[NSNumber numberWithInt: ABRecordGetRecordID(contact)]];
- } else {
- [avatarMap setObject:[NSNull null] forKey:[NSNumber numberWithInt: ABRecordGetRecordID(contact)]];
- }
- } else if(data != [NSNull null]) {
- image = data;
- }
- if(image == nil) {
- image = [UIImage imageNamed:@"avatar_unknown_small.png"];
- }
- [[cell avatarImage] setImage:image];
-
- [cell setContact: contact];
- return cell;
+ static NSString *kCellId = @"UIContactCell";
+ UIContactCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId];
+ if (cell == nil) {
+ cell = [[[UIContactCell alloc] initWithIdentifier:kCellId] autorelease];
+
+ // Background View
+ UACellBackgroundView *selectedBackgroundView = [[[UACellBackgroundView alloc] initWithFrame:CGRectZero] autorelease];
+ cell.selectedBackgroundView = selectedBackgroundView;
+ [selectedBackgroundView setBackgroundColor:LINPHONE_TABLE_CELL_BACKGROUND_COLOR];
+ }
+ OrderedDictionary *subDic = [addressBookMap objectForKey: [addressBookMap keyAtIndex: [indexPath section]]];
+
+ NSString *key = [[subDic allKeys] objectAtIndex:[indexPath row]];
+ ABRecordRef contact = [subDic objectForKey:key];
+
+ // Cached avatar
+ UIImage *image = nil;
+ id data = [avatarMap objectForKey:[NSNumber numberWithInt: ABRecordGetRecordID(contact)]];
+ if(data == nil) {
+ image = [FastAddressBook getContactImage:contact thumbnail:true];
+ if(image != nil) {
+ [avatarMap setObject:image forKey:[NSNumber numberWithInt: ABRecordGetRecordID(contact)]];
+ } else {
+ [avatarMap setObject:[NSNull null] forKey:[NSNumber numberWithInt: ABRecordGetRecordID(contact)]];
+ }
+ } else if(data != [NSNull null]) {
+ image = data;
+ }
+ if(image == nil) {
+ image = [UIImage imageNamed:@"avatar_unknown_small.png"];
+ }
+ [[cell avatarImage] setImage:image];
+
+ [cell setContact: contact];
+ return cell;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
- return [addressBookMap keyAtIndex: section];
+ return [addressBookMap keyAtIndex: section];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
- OrderedDictionary *subDic = [addressBookMap objectForKey: [addressBookMap keyAtIndex: [indexPath section]]];
- ABRecordRef lPerson = [subDic objectForKey: [subDic keyAtIndex:[indexPath row]]];
-
- // Go to Contact details view
- ContactDetailsViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ContactDetailsViewController compositeViewDescription] push:TRUE], ContactDetailsViewController);
- if(controller != nil) {
- if([ContactSelection getSelectionMode] != ContactSelectionModeEdit) {
- [controller setContact:lPerson];
- } else {
- [controller editContact:lPerson address:[ContactSelection getAddAddress]];
- }
- }
+ OrderedDictionary *subDic = [addressBookMap objectForKey: [addressBookMap keyAtIndex: [indexPath section]]];
+ ABRecordRef lPerson = [subDic objectForKey: [subDic keyAtIndex:[indexPath row]]];
+
+ // Go to Contact details view
+ ContactDetailsViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ContactDetailsViewController compositeViewDescription] push:TRUE], ContactDetailsViewController);
+ if(controller != nil) {
+ if([ContactSelection getSelectionMode] != ContactSelectionModeEdit) {
+ [controller setContact:lPerson];
+ } else {
+ [controller editContact:lPerson address:[ContactSelection getAddAddress]];
+ }
+ }
}
#pragma mark - UITableViewDelegate Functions
- (UITableViewCellEditingStyle)tableView:(UITableView *)aTableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
- // Detemine if it's in editing mode
- if (self.editing) {
- return UITableViewCellEditingStyleDelete;
- }
- return UITableViewCellEditingStyleNone;
+ // Detemine if it's in editing mode
+ if (self.editing) {
+ return UITableViewCellEditingStyleDelete;
+ }
+ return UITableViewCellEditingStyleNone;
}
@end
diff --git a/Classes/ContactsViewController.h b/Classes/ContactsViewController.h
index c580d82bf..a7a91c866 100644
--- a/Classes/ContactsViewController.h
+++ b/Classes/ContactsViewController.h
@@ -4,18 +4,18 @@
*
* 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
+ * 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.
- */
+ */
#import
#import
@@ -30,18 +30,48 @@ typedef enum _ContactSelectionMode {
ContactSelectionModeMessage
} ContactSelectionMode;
-@interface ContactSelection : NSObject {
+@interface ContactSelection : NSObject {
}
+ (void)setSelectionMode:(ContactSelectionMode)selectionMode;
+ (ContactSelectionMode)getSelectionMode;
+ (void)setAddAddress:(NSString*)address;
+ (NSString*)getAddAddress;
-/* define sip filter, can be * or sip domain*/
+/*!
+ * Filters contacts by SIP domain.
+ * @param domain SIP domain to filter. Use @"*" or nil to disable it.
+ */
+ (void)setSipFilter:(NSString*) domain;
+
+/*!
+ * Weither contacts are filtered by SIP domain or not.
+ * @return the filter used, or nil if none.
+ */
+ (NSString*)getSipFilter;
-+ (void)setEmailFilter:(BOOL)enable;
-+ (BOOL)getEmailFilter;
+
+/*!
+ * Weither always keep contacts with an email address or not.
+ * @param enable TRUE if you want to always keep contacts with an email.
+ */
++ (void)enableEmailFilter:(BOOL)enable;
+
+/*!
+ * Weither always keep contacts with an email address or not.
+ * @return TRUE if this behaviour is enabled.
+ */
++ (BOOL)emailFilterEnabled;
+
+/*!
+ * Filters contacts by name and/or email fuzzy matching pattern.
+ * @param fuzzyName fuzzy word to match. Use nil to disable it.
+ */
++ (void)setNameOrEmailFilter:(NSString*)fuzzyName;
+
+/*!
+ * Weither contacts are filtered by name and/or email.
+ * @return the filter used, or nil if none.
+ */
++ (NSString*)getNameOrEmailFilter;
@end
@@ -57,10 +87,12 @@ typedef enum _ContactSelectionMode {
@property (nonatomic, retain) IBOutlet UIButton* linphoneButton;
@property (nonatomic, retain) IBOutlet UIButton *backButton;
@property (nonatomic, retain) IBOutlet UIButton *addButton;
+@property (retain, nonatomic) IBOutlet UISearchBar *searchBar;
- (IBAction)onAllClick:(id)event;
- (IBAction)onLinphoneClick:(id)event;
- (IBAction)onAddContactClick:(id)event;
- (IBAction)onBackClick:(id)event;
+- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText;
@end
diff --git a/Classes/ContactsViewController.m b/Classes/ContactsViewController.m
index 621f3c13f..b2a898eba 100644
--- a/Classes/ContactsViewController.m
+++ b/Classes/ContactsViewController.m
@@ -4,18 +4,18 @@
*
* 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
+ * 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.
- */
+ */
#import "ContactsViewController.h"
#import "PhoneMainView.h"
@@ -28,47 +28,58 @@
static ContactSelectionMode sSelectionMode = ContactSelectionModeNone;
static NSString* sAddAddress = nil;
static NSString* sSipFilter = nil;
-static BOOL sEmailFilter = FALSE;
+static BOOL sEnableEmailFilter = FALSE;
+static NSString* sNameOrEmailFilter;
+ (void)setSelectionMode:(ContactSelectionMode)selectionMode {
- sSelectionMode = selectionMode;
+ sSelectionMode = selectionMode;
}
+ (ContactSelectionMode)getSelectionMode {
- return sSelectionMode;
+ return sSelectionMode;
}
+ (void)setAddAddress:(NSString*)address {
- if(sAddAddress != nil) {
- [sAddAddress release];
- sAddAddress= nil;
- }
- if(address != nil) {
- sAddAddress = [address retain];
- }
+ if(sAddAddress != nil) {
+ [sAddAddress release];
+ sAddAddress= nil;
+ }
+ if(address != nil) {
+ sAddAddress = [address retain];
+ }
}
+ (NSString*)getAddAddress {
- return sAddAddress;
+ return sAddAddress;
}
+ (void)setSipFilter:(NSString*)domain {
- [sSipFilter release];
+ [sSipFilter release];
sSipFilter = [domain retain];
}
+ (NSString*)getSipFilter {
- return sSipFilter;
+ return sSipFilter;
}
-+ (void)setEmailFilter:(BOOL)enable {
- sEmailFilter = enable;
++ (void)enableEmailFilter:(BOOL)enable {
+ sEnableEmailFilter = enable;
}
-+ (BOOL)getEmailFilter {
- return sEmailFilter;
++ (BOOL)emailFilterEnabled {
+ return sEnableEmailFilter;
}
++ (void)setNameOrEmailFilter:(NSString*)fuzzyName {
+ [sNameOrEmailFilter release];
+ sNameOrEmailFilter = [fuzzyName retain];
+}
+
++ (NSString*)getNameOrEmailFilter {
+ return sNameOrEmailFilter;
+}
+
+
@end
@implementation ContactsViewController
@@ -85,28 +96,30 @@ static BOOL sEmailFilter = FALSE;
@synthesize toolBar;
typedef enum _HistoryView {
- History_All,
- History_Linphone,
- History_MAX
+ History_All,
+ History_Linphone,
+ History_Search,
+ History_MAX
} HistoryView;
#pragma mark - Lifecycle Functions
- (id)init {
- return [super initWithNibName:@"ContactsViewController" bundle:[NSBundle mainBundle]];
+ return [super initWithNibName:@"ContactsViewController" bundle:[NSBundle mainBundle]];
}
- (void)dealloc {
- [tableController release];
- [tableView release];
-
- [allButton release];
- [linphoneButton release];
- [backButton release];
- [addButton release];
-
- [super dealloc];
+ [tableController release];
+ [tableView release];
+
+ [allButton release];
+ [linphoneButton release];
+ [backButton release];
+ [addButton release];
+
+ [_searchBar release];
+ [super dealloc];
}
#pragma mark - UICompositeViewDelegate Functions
@@ -114,181 +127,181 @@ typedef enum _HistoryView {
static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
- if(compositeDescription == nil) {
- compositeDescription = [[UICompositeViewDescription alloc] init:@"Contacts"
- content:@"ContactsViewController"
- stateBar:nil
- stateBarEnabled:false
- tabBar:@"UIMainBar"
- tabBarEnabled:true
- fullscreen:false
- landscapeMode:[LinphoneManager runningOnIpad]
- portraitMode:true];
- }
- return compositeDescription;
+ if(compositeDescription == nil) {
+ compositeDescription = [[UICompositeViewDescription alloc] init:@"Contacts"
+ content:@"ContactsViewController"
+ stateBar:nil
+ stateBarEnabled:false
+ tabBar:@"UIMainBar"
+ tabBarEnabled:true
+ fullscreen:false
+ landscapeMode:[LinphoneManager runningOnIpad]
+ portraitMode:true];
+ }
+ return compositeDescription;
}
#pragma mark - ViewController Functions
- (void)viewWillDisappear:(BOOL)animated {
- [super viewWillDisappear:animated];
+ [super viewWillDisappear:animated];
}
- (void)viewWillAppear:(BOOL)animated {
- [super viewWillAppear:animated];
-
- BOOL use_system = [[LinphoneManager instance] lpConfigBoolForKey:@"use_system_contacts"];
- if( use_system && !self.sysViewController){// use system contacts
- ABPeoplePickerNavigationController* picker = [[ABPeoplePickerNavigationController alloc] init];
- picker.peoplePickerDelegate = self;
- picker.view.frame = self.view.frame;
+ [super viewWillAppear:animated];
- [self.view addSubview:picker.view];
+ BOOL use_system = [[LinphoneManager instance] lpConfigBoolForKey:@"use_system_contacts"];
+ if( use_system && !self.sysViewController){// use system contacts
+ ABPeoplePickerNavigationController* picker = [[ABPeoplePickerNavigationController alloc] init];
+ picker.peoplePickerDelegate = self;
+ picker.view.frame = self.view.frame;
- self.sysViewController = picker;
+ [self.view addSubview:picker.view];
- } else if( !use_system && !self.tableController ){
+ self.sysViewController = picker;
- CGRect subViewFrame= self.view.frame;
- // let the toolBar be visible
- subViewFrame.origin.y += self.toolBar.frame.size.height;
- subViewFrame.size.height -= self.toolBar.frame.size.height;
+ } else if( !use_system && !self.tableController ){
- self.tableController = [[[ContactsTableViewController alloc] init] autorelease];
- self.tableView = [[[UITableView alloc] init] autorelease];
+ CGRect subViewFrame= self.view.frame;
+ // let the toolBar be visible
+ subViewFrame.origin.y += self.toolBar.frame.size.height;
+ subViewFrame.size.height -= self.toolBar.frame.size.height;
- self.tableController.view = self.tableView;
- self.tableView.frame = subViewFrame;
+ self.tableController = [[[ContactsTableViewController alloc] init] autorelease];
+ self.tableView = [[[UITableView alloc] init] autorelease];
- self.tableView.dataSource = self.tableController;
- self.tableView.delegate = self.tableController;
+ self.tableController.view = self.tableView;
+ self.tableView.frame = subViewFrame;
- self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight |
- UIViewAutoresizingFlexibleWidth |
- UIViewAutoresizingFlexibleTopMargin |
- UIViewAutoresizingFlexibleBottomMargin |
- UIViewAutoresizingFlexibleLeftMargin |
- UIViewAutoresizingFlexibleRightMargin;
+ self.tableView.dataSource = self.tableController;
+ self.tableView.delegate = self.tableController;
- [self.view addSubview:tableView];
- [self update];
- }
+ self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight |
+ UIViewAutoresizingFlexibleWidth |
+ UIViewAutoresizingFlexibleTopMargin |
+ UIViewAutoresizingFlexibleBottomMargin |
+ UIViewAutoresizingFlexibleLeftMargin |
+ UIViewAutoresizingFlexibleRightMargin;
+
+ [self.view addSubview:tableView];
+ [self update];
+ }
}
- (void)viewDidAppear:(BOOL)animated {
- [super viewDidAppear:animated];
- if(![FastAddressBook isAuthorized]) {
- UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Address book",nil)
+ [super viewDidAppear:animated];
+ if(![FastAddressBook isAuthorized]) {
+ UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Address book",nil)
message:NSLocalizedString(@"You must authorize the application to have access to address book.\n"
- "Toggle the application in Settings > Privacy > Contacts",nil)
+ "Toggle the application in Settings > Privacy > Contacts",nil)
delegate:nil
cancelButtonTitle:NSLocalizedString(@"Continue",nil)
otherButtonTitles:nil];
[error show];
[error release];
- [[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]];
- }
+ [[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]];
+ }
}
- (void)viewDidDisappear:(BOOL)animated {
- [super viewDidDisappear:animated];
+ [super viewDidDisappear:animated];
}
- (void)viewDidLoad {
- [super viewDidLoad];
-
- [self changeView:History_All];
-
- // Set selected+over background: IB lack !
- [linphoneButton setBackgroundImage:[UIImage imageNamed:@"contacts_linphone_selected.png"]
- forState:(UIControlStateHighlighted | UIControlStateSelected)];
-
- [linphoneButton setTitle:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]
+ [super viewDidLoad];
+
+ [self changeView:History_All];
+
+ // Set selected+over background: IB lack !
+ [linphoneButton setBackgroundImage:[UIImage imageNamed:@"contacts_linphone_selected.png"]
+ forState:(UIControlStateHighlighted | UIControlStateSelected)];
+
+ [linphoneButton setTitle:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]
forState:UIControlStateNormal];
-
+
[LinphoneUtils buttonFixStates:linphoneButton];
-
- // Set selected+over background: IB lack !
- [allButton setBackgroundImage:[UIImage imageNamed:@"contacts_all_selected.png"]
- forState:(UIControlStateHighlighted | UIControlStateSelected)];
-
- [LinphoneUtils buttonFixStates:allButton];
-
- [tableController.tableView setBackgroundColor:[UIColor clearColor]]; // Can't do it in Xib: issue with ios4
- [tableController.tableView setBackgroundView:nil]; // Can't do it in Xib: issue with ios4
+
+ // Set selected+over background: IB lack !
+ [allButton setBackgroundImage:[UIImage imageNamed:@"contacts_all_selected.png"]
+ forState:(UIControlStateHighlighted | UIControlStateSelected)];
+
+ [LinphoneUtils buttonFixStates:allButton];
+
+ [tableController.tableView setBackgroundColor:[UIColor clearColor]]; // Can't do it in Xib: issue with ios4
+ [tableController.tableView setBackgroundView:nil]; // Can't do it in Xib: issue with ios4
}
#pragma mark -
- (void)changeView:(HistoryView)view {
- if(view == History_All) {
- [ContactSelection setSipFilter:nil];
- [ContactSelection setEmailFilter:FALSE];
- [tableController loadData];
- allButton.selected = TRUE;
- } else {
- allButton.selected = FALSE;
- }
+ if(view == History_All) {
+ [ContactSelection setSipFilter:nil];
+ [ContactSelection enableEmailFilter:FALSE];
+ [tableController loadData];
+ allButton.selected = TRUE;
+ } else {
+ allButton.selected = FALSE;
+ }
- if(view == History_Linphone) {
- [ContactSelection setSipFilter:[LinphoneManager instance].contactFilter];
- [ContactSelection setEmailFilter:FALSE];
- [tableController loadData];
- linphoneButton.selected = TRUE;
- } else {
- linphoneButton.selected = FALSE;
- }
+ if(view == History_Linphone) {
+ [ContactSelection setSipFilter:[LinphoneManager instance].contactFilter];
+ [ContactSelection enableEmailFilter:FALSE];
+ [tableController loadData];
+ linphoneButton.selected = TRUE;
+ } else {
+ linphoneButton.selected = FALSE;
+ }
}
- (void)update {
- switch ([ContactSelection getSelectionMode]) {
- case ContactSelectionModePhone:
- case ContactSelectionModeMessage:
- [addButton setHidden:TRUE];
- [backButton setHidden:FALSE];
- break;
- default:
- [addButton setHidden:FALSE];
- [backButton setHidden:TRUE];
- break;
- }
- if([ContactSelection getSipFilter]) {
- allButton.selected = FALSE;
- linphoneButton.selected = TRUE;
- } else {
- allButton.selected = TRUE;
- linphoneButton.selected = FALSE;
- }
- [tableController loadData];
+ switch ([ContactSelection getSelectionMode]) {
+ case ContactSelectionModePhone:
+ case ContactSelectionModeMessage:
+ [addButton setHidden:TRUE];
+ [backButton setHidden:FALSE];
+ break;
+ default:
+ [addButton setHidden:FALSE];
+ [backButton setHidden:TRUE];
+ break;
+ }
+ if([ContactSelection getSipFilter]) {
+ allButton.selected = FALSE;
+ linphoneButton.selected = TRUE;
+ } else {
+ allButton.selected = TRUE;
+ linphoneButton.selected = FALSE;
+ }
+ [tableController loadData];
}
#pragma mark - Action Functions
- (IBAction)onAllClick:(id)event {
- [self changeView: History_All];
+ [self changeView: History_All];
}
- (IBAction)onLinphoneClick:(id)event {
- [self changeView: History_Linphone];
+ [self changeView: History_Linphone];
}
- (IBAction)onAddContactClick:(id)event {
- // Go to Contact details view
- ContactDetailsViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ContactDetailsViewController compositeViewDescription] push:TRUE], ContactDetailsViewController);
- if(controller != nil) {
- if([ContactSelection getAddAddress] == nil) {
- [controller newContact];
- } else {
- [controller newContact:[ContactSelection getAddAddress]];
- }
- }
+ // Go to Contact details view
+ ContactDetailsViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ContactDetailsViewController compositeViewDescription] push:TRUE], ContactDetailsViewController);
+ if(controller != nil) {
+ if([ContactSelection getAddAddress] == nil) {
+ [controller newContact];
+ } else {
+ [controller newContact:[ContactSelection getAddAddress]];
+ }
+ }
}
- (IBAction)onBackClick:(id)event {
- [[PhoneMainView instance] popCurrentView];
+ [[PhoneMainView instance] popCurrentView];
}
@@ -296,8 +309,8 @@ static UICompositeViewDescription *compositeDescription = nil;
-(void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker
{
- [[PhoneMainView instance] popCurrentView];
- return;
+ [[PhoneMainView instance] popCurrentView];
+ return;
}
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
@@ -314,19 +327,23 @@ static UICompositeViewDescription *compositeDescription = nil;
CFTypeRef multiValue = ABRecordCopyValue(person, property);
CFIndex valueIdx = ABMultiValueGetIndexForIdentifier(multiValue,identifier);
NSString *phoneNumber = (NSString *)ABMultiValueCopyValueAtIndex(multiValue, valueIdx);
- // Go to dialer view
- DialerViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]], DialerViewController);
- if(controller != nil) {
- [controller call:phoneNumber displayName:[(NSString*)ABRecordCopyCompositeName(person) autorelease]];
- }
- [phoneNumber release];
- CFRelease(multiValue);
+ // Go to dialer view
+ DialerViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]], DialerViewController);
+ if(controller != nil) {
+ [controller call:phoneNumber displayName:[(NSString*)ABRecordCopyCompositeName(person) autorelease]];
+ }
+ [phoneNumber release];
+ CFRelease(multiValue);
return false;
}
+- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
+ [ContactSelection setNameOrEmailFilter:searchText];
+ [tableController loadData];
+}
- (void)viewDidUnload {
- [self setToolBar:nil];
- [super viewDidUnload];
+ [self setToolBar:nil];
+ [super viewDidUnload];
}
@end
diff --git a/Classes/DialerViewController.m b/Classes/DialerViewController.m
index 7a0a37efe..42472a630 100644
--- a/Classes/DialerViewController.m
+++ b/Classes/DialerViewController.m
@@ -4,18 +4,18 @@
*
* 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
+ * 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.
- */
+ */
#import
#import
@@ -76,7 +76,7 @@
[callButton release];
[addCallButton release];
[transferButton release];
-
+
[oneButton release];
[twoButton release];
[threeButton release];
@@ -89,13 +89,13 @@
[starButton release];
[zeroButton release];
[sharpButton release];
-
+
[videoPreview release];
[videoCameraSwitch release];
-
+
// Remove all observers
[[NSNotificationCenter defaultCenter] removeObserver:self];
-
+
[super dealloc];
}
@@ -106,15 +106,16 @@ static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
if(compositeDescription == nil) {
- compositeDescription = [[UICompositeViewDescription alloc] init:@"Dialer"
- content:@"DialerViewController"
- stateBar:@"UIStateBar"
- stateBarEnabled:true
- tabBar:@"UIMainBar"
- tabBarEnabled:true
+ compositeDescription = [[UICompositeViewDescription alloc] init:@"Dialer"
+ content:@"DialerViewController"
+ stateBar:@"UIStateBar"
+ stateBarEnabled:true
+ tabBar:@"UIMainBar"
+ tabBarEnabled:true
fullscreen:false
landscapeMode:[LinphoneManager runningOnIpad]
portraitMode:true];
+ compositeDescription.darkBackground = true;
}
return compositeDescription;
}
@@ -124,13 +125,13 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
-
+
// Set observer
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(callUpdateEvent:)
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(callUpdateEvent:)
name:kLinphoneCallUpdate
object:nil];
-
+
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(coreUpdateEvent:)
name:kLinphoneCoreUpdate
@@ -178,16 +179,16 @@ static UICompositeViewDescription *compositeDescription = nil;
#endif
}
-}
+}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
-
+
// Remove observer
- [[NSNotificationCenter defaultCenter] removeObserver:self
+ [[NSNotificationCenter defaultCenter] removeObserver:self
name:kLinphoneCallUpdate
object:nil];
-
+
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kLinphoneCoreUpdate
object:nil];
@@ -195,7 +196,7 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)viewDidLoad {
[super viewDidLoad];
-
+
[zeroButton setDigit:'0'];
[oneButton setDigit:'1'];
[twoButton setDigit:'2'];
@@ -208,9 +209,9 @@ static UICompositeViewDescription *compositeDescription = nil;
[nineButton setDigit:'9'];
[starButton setDigit:'*'];
[sharpButton setDigit:'#'];
-
+
[addressField setAdjustsFontSizeToFitWidth:TRUE]; // Not put it in IB: issue with placeholder size
-
+
if([LinphoneManager runningOnIpad]) {
if ([LinphoneManager instance].frontCamId != nil) {
// only show camera switch button if we have more than 1 camera
@@ -248,7 +249,7 @@ static UICompositeViewDescription *compositeDescription = nil;
#pragma mark - Event Functions
-- (void)callUpdateEvent:(NSNotification*)notif {
+- (void)callUpdateEvent:(NSNotification*)notif {
LinphoneCall *call = [[notif.userInfo objectForKey: @"call"] pointerValue];
LinphoneCallState state = [[notif.userInfo objectForKey: @"state"] intValue];
[self callUpdate:call state:state];
@@ -283,7 +284,7 @@ static UICompositeViewDescription *compositeDescription = nil;
[transferButton setHidden:true];
}
[callButton setHidden:true];
- [backButton setHidden:false];
+ [backButton setHidden:false];
[addContactButton setHidden:true];
} else {
[addCallButton setHidden:true];
@@ -330,7 +331,7 @@ static UICompositeViewDescription *compositeDescription = nil;
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
if (textField == addressField) {
[addressField resignFirstResponder];
- }
+ }
return YES;
}
@@ -341,10 +342,11 @@ static UICompositeViewDescription *compositeDescription = nil;
[ContactSelection setSelectionMode:ContactSelectionModeEdit];
[ContactSelection setAddAddress:[addressField text]];
[ContactSelection setSipFilter:nil];
- [ContactSelection setEmailFilter:FALSE];
+ [ContactSelection setNameOrEmailFilter:nil];
+ [ContactSelection enableEmailFilter:FALSE];
ContactsViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ContactsViewController compositeViewDescription] push:TRUE], ContactsViewController);
if(controller != nil) {
-
+
}
}
diff --git a/Classes/HistoryDetailsViewController.m b/Classes/HistoryDetailsViewController.m
index dfaf43580..e327e4040 100644
--- a/Classes/HistoryDetailsViewController.m
+++ b/Classes/HistoryDetailsViewController.m
@@ -4,18 +4,18 @@
*
* 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
+ * 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.
- */
+ */
#import "HistoryDetailsViewController.h"
#import "PhoneMainView.h"
@@ -55,10 +55,10 @@
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
-
+
[dateFormatter release];
[callLogId release];
-
+
[avatarImage release];
[addressLabel release];
[dateLabel release];
@@ -72,7 +72,7 @@
[callButton release];
[messageButton release];
[addContactButton release];
-
+
[super dealloc];
}
@@ -83,12 +83,12 @@ static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
if(compositeDescription == nil) {
- compositeDescription = [[UICompositeViewDescription alloc] init:@"HistoryDetails"
- content:@"HistoryDetailsViewController"
- stateBar:nil
- stateBarEnabled:false
- tabBar:@"UIMainBar"
- tabBarEnabled:true
+ compositeDescription = [[UICompositeViewDescription alloc] init:@"HistoryDetails"
+ content:@"HistoryDetailsViewController"
+ stateBar:nil
+ stateBarEnabled:false
+ tabBar:@"UIMainBar"
+ tabBarEnabled:true
fullscreen:false
landscapeMode:[LinphoneManager runningOnIpad]
portraitMode:true];
@@ -124,12 +124,12 @@ static UICompositeViewDescription *compositeDescription = nil;
if( use_system ){
[addContactButton setHidden:TRUE];
}
-
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(update)
+
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(update)
name:kLinphoneAddressBookUpdate
object:nil];
-
+
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(coreUpdateEvent:)
name:kLinphoneCoreUpdate
@@ -138,11 +138,11 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
-
- [[NSNotificationCenter defaultCenter] removeObserver:self
+
+ [[NSNotificationCenter defaultCenter] removeObserver:self
name:kLinphoneAddressBookUpdate
object:nil];
-
+
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kLinphoneCoreUpdate
object:nil];
@@ -156,7 +156,7 @@ static UICompositeViewDescription *compositeDescription = nil;
}
-#pragma mark -
+#pragma mark -
+ (void)adaptSize:(UILabel*)label field:(UIView*)field {
//
@@ -164,20 +164,20 @@ static UICompositeViewDescription *compositeDescription = nil;
//
CGRect labelFrame = [label frame];
CGRect fieldFrame = [field frame];
-
+
fieldFrame.origin.x -= labelFrame.size.width;
-
+
// Compute firstName size
CGSize contraints;
contraints.height = [label frame].size.height;
contraints.width = ([field frame].size.width + [field frame].origin.x) - [label frame].origin.x;
CGSize firstNameSize = [[label text] sizeWithFont:[label font] constrainedToSize: contraints];
labelFrame.size.width = firstNameSize.width;
-
+
// Compute lastName size & position
fieldFrame.origin.x += labelFrame.size.width;
fieldFrame.size.width = (contraints.width + [label frame].origin.x) - fieldFrame.origin.x;
-
+
[label setFrame: labelFrame];
[field setFrame: fieldFrame];
}
@@ -186,7 +186,7 @@ static UICompositeViewDescription *compositeDescription = nil;
if(![LinphoneManager isLcReady]) {
return;
}
-
+
// Look for the call log
callLog = NULL;
const MSList *list = linphone_core_get_call_logs([LinphoneManager getLc]);
@@ -199,20 +199,20 @@ static UICompositeViewDescription *compositeDescription = nil;
}
list = list->next;
}
-
+
// Pop if callLog is null
if(callLog == NULL) {
[[PhoneMainView instance] popCurrentView];
return;
}
-
+
LinphoneAddress* addr =linphone_call_log_get_remote_address(callLog);
-
+
UIImage *image = nil;
NSString* address = nil;
if(addr != NULL) {
BOOL useLinphoneAddress = true;
- // contact name
+ // contact name
char* lAddress = linphone_address_as_string_uri_only(addr);
if(lAddress) {
NSString *normalizedSipAddress = [FastAddressBook normalizeSipURI:[NSString stringWithUTF8String:lAddress]];
@@ -227,25 +227,25 @@ static UICompositeViewDescription *compositeDescription = nil;
if(useLinphoneAddress) {
const char* lDisplayName = linphone_address_get_display_name(addr);
const char* lUserName = linphone_address_get_username(addr);
- if (lDisplayName)
+ if (lDisplayName)
address = [NSString stringWithUTF8String:lDisplayName];
- else if(lUserName)
+ else if(lUserName)
address = [NSString stringWithUTF8String:lUserName];
}
}
-
+
// Set Image
if(image == nil) {
image = [UIImage imageNamed:@"avatar_unknown.png"];
}
[avatarImage setImage:image];
-
+
// Set Address
if(address == nil) {
address = NSLocalizedString(@"Unknown", nil);
}
[addressLabel setText:address];
-
+
// Hide/Show add button
BOOL use_system = [[LinphoneManager instance] lpConfigBoolForKey:@"use_system_contacts"];
if(contact) {
@@ -253,7 +253,7 @@ static UICompositeViewDescription *compositeDescription = nil;
} else if (!use_system) {
[addContactButton setHidden:FALSE];
}
-
+
// State
NSMutableString *state = [NSMutableString string];
if (linphone_call_log_get_dir(callLog) == LinphoneCallIncoming) {
@@ -283,7 +283,7 @@ static UICompositeViewDescription *compositeDescription = nil;
// Duration
int duration = linphone_call_log_get_duration(callLog);
[durationLabel setText:[NSString stringWithFormat:@"%02i:%02i", (duration/60), duration - 60 * (duration / 60), nil]];
-
+
// contact name
[plainAddressLabel setText:@""];
if (addr != NULL) {
@@ -297,7 +297,7 @@ static UICompositeViewDescription *compositeDescription = nil;
}
}
}
-
+
if (addr != NULL) {
[callButton setHidden:FALSE];
[messageButton setHidden:FALSE];
@@ -305,7 +305,7 @@ static UICompositeViewDescription *compositeDescription = nil;
[callButton setHidden:TRUE];
[messageButton setHidden:TRUE];
}
-
+
}
@@ -327,16 +327,17 @@ static UICompositeViewDescription *compositeDescription = nil;
- (IBAction)onAddContactClick:(id)event {
LinphoneAddress* addr;
-
+
addr=linphone_call_log_get_remote_address(callLog);
if (addr != NULL) {
char* lAddress = linphone_address_as_string_uri_only(addr);
if(lAddress != NULL) {
[ContactSelection setAddAddress:[NSString stringWithUTF8String:lAddress]];
[ContactSelection setSelectionMode:ContactSelectionModeEdit];
-
+
[ContactSelection setSipFilter:nil];
- [ContactSelection setEmailFilter:FALSE];
+ [ContactSelection enableEmailFilter:FALSE];
+ [ContactSelection setNameOrEmailFilter:nil];
ContactsViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ContactsViewController compositeViewDescription] push:TRUE], ContactsViewController);
if(controller != nil) {
}
@@ -346,26 +347,26 @@ static UICompositeViewDescription *compositeDescription = nil;
}
- (IBAction)onCallClick:(id)event {
- LinphoneAddress* addr;
+ LinphoneAddress* addr;
addr=linphone_call_log_get_remote_address(callLog);
-
+
char* lAddress = linphone_address_as_string_uri_only(addr);
- if(lAddress == NULL)
+ if(lAddress == NULL)
return;
-
+
NSString *displayName = nil;
if(contact != nil) {
- displayName = [FastAddressBook getContactDisplayName:contact];
+ displayName = [FastAddressBook getContactDisplayName:contact];
} else {
const char* lDisplayName = linphone_address_get_display_name(addr);
const char* lUserName = linphone_address_get_username(addr);
- if (lDisplayName)
+ if (lDisplayName)
displayName = [NSString stringWithUTF8String:lDisplayName];
- else if(lUserName)
+ else if(lUserName)
displayName = [NSString stringWithUTF8String:lUserName];
}
-
-
+
+
DialerViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]], DialerViewController);
if(controller != nil) {
if(displayName != nil) {
@@ -380,11 +381,11 @@ static UICompositeViewDescription *compositeDescription = nil;
- (IBAction)onMessageClick:(id)event {
LinphoneAddress* addr;
addr=linphone_call_log_get_remote_address(callLog);
-
+
char* lAddress = linphone_address_as_string_uri_only(addr);
if(lAddress == NULL)
return;
-
+
NSString *displayName = nil;
if(contact != nil) {
displayName = [FastAddressBook getContactDisplayName:contact];
@@ -396,7 +397,7 @@ static UICompositeViewDescription *compositeDescription = nil;
else if(lUserName)
displayName = [NSString stringWithUTF8String:lUserName];
}
-
+
// Go to ChatRoom view
[[PhoneMainView instance] changeCurrentView:[ChatViewController compositeViewDescription]];
ChatRoomViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ChatRoomViewController compositeViewDescription] push:TRUE], ChatRoomViewController);
diff --git a/Classes/InCallViewController.m b/Classes/InCallViewController.m
index 2009b3463..fda5ce633 100644
--- a/Classes/InCallViewController.m
+++ b/Classes/InCallViewController.m
@@ -105,6 +105,7 @@ static UICompositeViewDescription *compositeDescription = nil;
fullscreen:false
landscapeMode:true
portraitMode:true];
+ compositeDescription.darkBackground = true;
}
return compositeDescription;
}
@@ -129,9 +130,6 @@ static UICompositeViewDescription *compositeDescription = nil;
[hideControlsTimer invalidate];
hideControlsTimer = nil;
}
- if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) {
- [callTableController viewWillDisappear:animated];
- }
if( hiddenVolume ) {
[[PhoneMainView instance] setVolumeHidden:FALSE];
@@ -146,10 +144,6 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
- if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) {
- [callTableController viewWillAppear:animated];
- }
-
// Set observer
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(callUpdateEvent:)
@@ -160,11 +154,7 @@ static UICompositeViewDescription *compositeDescription = nil;
LinphoneCall* call = linphone_core_get_current_call([LinphoneManager getLc]);
LinphoneCallState state = (call != NULL)?linphone_call_get_state(call): 0;
[self callUpdate:call state:state animated:FALSE];
-
- if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) {
- [callTableController viewDidAppear:animated];
- }
-
+
// Set windows (warn memory leaks)
linphone_core_set_native_video_window_id([LinphoneManager getLc], (unsigned long)videoView);
linphone_core_set_native_preview_window_id([LinphoneManager getLc], (unsigned long)videoPreview);
@@ -179,11 +169,7 @@ static UICompositeViewDescription *compositeDescription = nil;
[[UIApplication sharedApplication] setIdleTimerDisabled:false];
UIDevice *device = [UIDevice currentDevice];
device.proximityMonitoringEnabled = NO;
-
- if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) {
- [callTableController viewDidDisappear:animated];
- }
-
+
[[PhoneMainView instance] fullScreen:false];
// Disable tap
[singleFingerTap setEnabled:FALSE];
diff --git a/Classes/IncomingCallViewController.m b/Classes/IncomingCallViewController.m
index e008d5c09..5c7519c92 100644
--- a/Classes/IncomingCallViewController.m
+++ b/Classes/IncomingCallViewController.m
@@ -81,6 +81,7 @@ static UICompositeViewDescription *compositeDescription = nil;
fullscreen:false
landscapeMode:[LinphoneManager runningOnIpad]
portraitMode:true];
+ compositeDescription.darkBackground = true;
}
return compositeDescription;
}
diff --git a/Classes/LinphoneAppDelegate.h b/Classes/LinphoneAppDelegate.h
index bc687d8dd..1e2af5e9a 100644
--- a/Classes/LinphoneAppDelegate.h
+++ b/Classes/LinphoneAppDelegate.h
@@ -23,13 +23,8 @@
#import "LinphoneCoreSettingsStore.h"
-@interface UILinphoneWindow : UIWindow
-
-@end
-
@interface LinphoneAppDelegate : NSObject {
@private
- UIWindow *window;
UIBackgroundTaskIdentifier bgStartId;
BOOL started;
int savedMaxCall;
@@ -40,6 +35,7 @@
@property (assign) BOOL started;
@property (nonatomic, retain) UIAlertView *waitingIndicator;
@property (nonatomic, retain) NSString *configURL;
+@property (nonatomic, strong) UIWindow* window;
@end
diff --git a/Classes/LinphoneAppDelegate.m b/Classes/LinphoneAppDelegate.m
index c2db65be7..4c4b62052 100644
--- a/Classes/LinphoneAppDelegate.m
+++ b/Classes/LinphoneAppDelegate.m
@@ -30,14 +30,10 @@
#include "LinphoneManager.h"
#include "linphone/linphonecore.h"
-@implementation UILinphoneWindow
-
-@end
-
@implementation LinphoneAppDelegate
@synthesize started,configURL;
-
+@synthesize window;
#pragma mark - Lifecycle Functions
@@ -118,10 +114,77 @@
}
}
+- (UIUserNotificationCategory*)newMessageNotificationCategory {
+
+ UIMutableUserNotificationAction* reply = [[UIMutableUserNotificationAction alloc] init];
+ reply.identifier = @"reply";
+ reply.title = NSLocalizedString(@"Reply", nil);
+ reply.activationMode = UIUserNotificationActivationModeForeground;
+ reply.destructive = NO;
+ reply.authenticationRequired = YES;
+
+ UIMutableUserNotificationAction* mark_read = [[UIMutableUserNotificationAction alloc] init];
+ mark_read.identifier = @"mark_read";
+ mark_read.title = NSLocalizedString(@"Mark Read", nil);
+ mark_read.activationMode = UIUserNotificationActivationModeBackground;
+ mark_read.destructive = NO;
+ mark_read.authenticationRequired = NO;
+
+
+ NSArray* localRingActions = @[mark_read, reply];
+
+ UIMutableUserNotificationCategory* localRingNotifAction = [[UIMutableUserNotificationCategory alloc] init];
+ localRingNotifAction.identifier = @"incoming_msg";
+ [localRingNotifAction setActions:localRingActions forContext:UIUserNotificationActionContextDefault];
+ [localRingNotifAction setActions:localRingActions forContext:UIUserNotificationActionContextMinimal];
+
+ return localRingNotifAction;
+}
+
+- (UIUserNotificationCategory*)newCallNotificationCategory {
+ UIMutableUserNotificationAction* Answer = [[UIMutableUserNotificationAction alloc] init];
+ Answer.identifier = @"answer";
+ Answer.title = NSLocalizedString(@"Answer", nil);
+ Answer.activationMode = UIUserNotificationActivationModeForeground;
+ Answer.destructive = NO;
+ Answer.authenticationRequired = YES;
+
+ UIMutableUserNotificationAction* Decline = [[UIMutableUserNotificationAction alloc] init];
+ Decline.identifier = @"decline";
+ Decline.title = NSLocalizedString(@"Decline", nil);
+ Decline.activationMode = UIUserNotificationActivationModeBackground;
+ Decline.destructive = YES;
+ Decline.authenticationRequired = NO;
+
+
+ NSArray* localRingActions = @[Decline, Answer];
+
+ UIMutableUserNotificationCategory* localRingNotifAction = [[UIMutableUserNotificationCategory alloc] init];
+ localRingNotifAction.identifier = @"incoming_call";
+ [localRingNotifAction setActions:localRingActions forContext:UIUserNotificationActionContextDefault];
+ [localRingNotifAction setActions:localRingActions forContext:UIUserNotificationActionContextMinimal];
+
+ return localRingNotifAction;
+}
+
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
- [[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeSound|UIRemoteNotificationTypeBadge|UIRemoteNotificationTypeNewsstandContentAvailability];
+
+ UIApplication* app= [UIApplication sharedApplication];
+
+ if( [app respondsToSelector:@selector(registerUserNotificationSettings:)] ){
+ /* iOS8 notifications can be actioned! Awesome: */
+ UIUserNotificationType notifTypes = UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert;
+
+ NSSet* categories = [NSSet setWithObjects:[self newCallNotificationCategory], [self newMessageNotificationCategory], nil];
+ UIUserNotificationSettings* userSettings = [UIUserNotificationSettings settingsForTypes:notifTypes categories:categories];
+ [app registerUserNotificationSettings:userSettings];
+ [app registerForRemoteNotifications];
+ } else {
+ NSUInteger notifTypes = UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeSound|UIRemoteNotificationTypeBadge|UIRemoteNotificationTypeNewsstandContentAvailability;
+ [app registerForRemoteNotificationTypes:notifTypes];
+ }
LinphoneManager* instance = [LinphoneManager instance];
@@ -167,6 +230,8 @@
// Only execute one time at application start
if(!started) {
started = TRUE;
+ [self.window makeKeyAndVisible];
+ [RootViewManager setupWithPortrait:(PhoneMainView*)self.window.rootViewController];
[[PhoneMainView instance] startUp];
}
}
@@ -353,6 +418,43 @@
[[LinphoneManager instance] setPushNotificationToken:nil];
}
+#pragma mark - User notifications
+
+- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
+ [LinphoneLogger log:LinphoneLoggerLog format:@"%@", NSStringFromSelector(_cmd)];
+}
+
+- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler {
+ LinphoneCore* lc = [LinphoneManager getLc];
+ [LinphoneLogger log:LinphoneLoggerLog format:@"%@", NSStringFromSelector(_cmd)];
+ if( [notification.category isEqualToString:@"incoming_call"]) {
+ if( [identifier isEqualToString:@"answer"] ){
+ // use the standard handler
+ [self application:application didReceiveLocalNotification:notification];
+ } else if( [identifier isEqualToString:@"decline"] ){
+ LinphoneCall* call = linphone_core_get_current_call(lc);
+ if( call ) linphone_core_decline_call(lc, call, LinphoneReasonDeclined);
+ }
+ } else if( [notification.category isEqualToString:@"incoming_msg"] ){
+ if( [identifier isEqualToString:@"reply"] ){
+ // use the standard handler
+ [self application:application didReceiveLocalNotification:notification];
+ } else if( [identifier isEqualToString:@"mark_read"] ){
+ NSString* from = [notification.userInfo objectForKey:@"from"];
+ LinphoneChatRoom* room = linphone_core_get_or_create_chat_room(lc, [from UTF8String]);
+ if( room ){
+ linphone_chat_room_mark_as_read(room);
+ [[PhoneMainView instance] updateApplicationBadgeNumber];
+ }
+ }
+ }
+ completionHandler();
+}
+
+- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler {
+ completionHandler();
+}
+
#pragma mark - Remote configuration Functions (URL Handler)
diff --git a/Classes/LinphoneCoreSettingsStore.m b/Classes/LinphoneCoreSettingsStore.m
index 16d58ba71..e1a55a2a2 100644
--- a/Classes/LinphoneCoreSettingsStore.m
+++ b/Classes/LinphoneCoreSettingsStore.m
@@ -4,18 +4,18 @@
*
* 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
+ * 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.
- */
+ */
#import "LinphoneCoreSettingsStore.h"
@@ -43,14 +43,14 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
- (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];
- [obj release];
+ [obj release];
}
- (NSString*)stringForKey:(NSString*) key {
@@ -64,7 +64,7 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
PayloadType *pt=(PayloadType*)elem->data;
NSString *pref=[LinphoneManager getPreferenceForCodec:pt->mime_type withRate:pt->clock_rate];
if (pref){
- bool_t value = linphone_core_payload_type_enabled(lc,pt);
+ bool_t value = linphone_core_payload_type_enabled(lc,pt);
[self setBool:value forKey: pref];
}else{
[LinphoneLogger logc:LinphoneLoggerWarning format:"Codec %s/%i supported by core is not shown in iOS app config view.",
@@ -76,7 +76,7 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
- (void)transformLinphoneCoreToKeys {
LinphoneCore *lc=[LinphoneManager getLc];
LinphoneProxyConfig *cfg=NULL;
- LpConfig* conf = linphone_core_get_config(lc);
+ LpConfig* conf = linphone_core_get_config(lc);
linphone_core_get_default_proxy(lc,&cfg);
if (cfg){
const char *identity=linphone_proxy_config_get_identity(cfg);
@@ -85,10 +85,10 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
const char *proxy=linphone_proxy_config_get_addr(cfg);
LinphoneAddress *proxy_addr=linphone_address_new(proxy);
int 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"];
- [self setInteger: linphone_proxy_config_get_expires(cfg) forKey:@"expire_preference"];
+ [self setInteger: linphone_proxy_config_get_expires(cfg) forKey:@"expire_preference"];
[self setString: linphone_proxy_config_get_dial_prefix(cfg) forKey:@"prefix_preference"];
if (strcmp(linphone_address_get_domain(addr),linphone_address_get_domain(proxy_addr))!=0 || port>0){
char tmp[256]={0};
@@ -98,74 +98,74 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
[self setString:tmp forKey:@"proxy_preference"];
}
- const char* tname = "udp";
- switch (linphone_address_get_transport(proxy_addr)) {
- case LinphoneTransportTcp: tname = "tcp"; break;
- case LinphoneTransportTls: tname = "tls"; break;
- default: break;
- }
- [self setString:tname forKey:@"transport_preference"];
+ const char* tname = "udp";
+ switch (linphone_address_get_transport(proxy_addr)) {
+ case LinphoneTransportTcp: tname = "tcp"; break;
+ case LinphoneTransportTls: tname = "tls"; break;
+ default: break;
+ }
+ [self setString:tname forKey:@"transport_preference"];
linphone_address_destroy(addr);
linphone_address_destroy(proxy_addr);
- [self setBool: (linphone_proxy_config_get_route(cfg)!=NULL) forKey:@"outbound_proxy_preference"];
+ [self setBool:(linphone_proxy_config_get_route(cfg)!=NULL) forKey:@"outbound_proxy_preference"];
[self setBool:linphone_proxy_config_get_dial_escape_plus(cfg) forKey:@"substitute_+_by_00_preference"];
- [self setBool:linphone_proxy_config_avpf_enabled(cfg) forKey:@"avpf_preference"];
-
+ [self setBool:linphone_proxy_config_avpf_enabled(cfg) forKey:@"avpf_preference"];
+
}
} else {
[self setInteger: lp_config_get_int(conf,"default_values","reg_expires", 600) forKey:@"expire_preference"];
- [self setObject:@"" forKey:@"username_preference"];
- [self setObject:@"" forKey:@"domain_preference"];
- [self setObject:@"" forKey:@"proxy_preference"];
- [self setObject:@"" forKey:@"password_preference"];
- [self setBool:FALSE forKey:@"outbound_proxy_preference"];
- [self setString:"udp" forKey:@"transport_preference"];
- [self setBool:FALSE forKey:@"avpf_preference"];
+ [self setObject:@"" forKey:@"username_preference"];
+ [self setObject:@"" forKey:@"domain_preference"];
+ [self setObject:@"" forKey:@"proxy_preference"];
+ [self setObject:@"" forKey:@"password_preference"];
+ [self setBool:FALSE forKey:@"outbound_proxy_preference"];
+ [self setString:"udp" forKey:@"transport_preference"];
+ [self setBool:FALSE forKey:@"avpf_preference"];
}
- [self setBool:lp_config_get_int(conf, LINPHONERC_APPLICATION_KEY, "pushnotification_preference", 0) forKey:@"pushnotification_preference"];
- {
- LinphoneAddress *parsed = linphone_core_get_primary_contact_parsed(lc);
- if(parsed != NULL) {
- [self setString: linphone_address_get_display_name(parsed) forKey:@"primary_displayname_preference"];
- [self setString: linphone_address_get_username(parsed) forKey:@"primary_username_preference"];
- }
- linphone_address_destroy(parsed);
- }
- {
- {
- int minPort, maxPort;
- linphone_core_get_audio_port_range(lc, &minPort, &maxPort);
- if(minPort != maxPort)
- [self setObject:[NSString stringWithFormat:@"%d-%d", minPort, maxPort] forKey:@"audio_port_preference"];
- else
- [self setObject:[NSString stringWithFormat:@"%d", minPort] forKey:@"audio_port_preference"];
- }
- {
- int minPort, maxPort;
- linphone_core_get_video_port_range(lc, &minPort, &maxPort);
- if(minPort != maxPort)
- [self setObject:[NSString stringWithFormat:@"%d-%d", minPort, maxPort] forKey:@"video_port_preference"];
- else
- [self setObject:[NSString stringWithFormat:@"%d", minPort] forKey:@"video_port_preference"];
- }
- }
- {
- [self setInteger: linphone_core_get_upload_bandwidth(lc) forKey:@"upload_bandwidth_preference"];
- [self setInteger: linphone_core_get_download_bandwidth(lc) forKey:@"download_bandwidth_preference"];
- }
- {
- [self setFloat:linphone_core_get_playback_gain_db(lc) forKey:@"playback_gain_preference"];
- [self setFloat:linphone_core_get_mic_gain_db(lc) forKey:@"microphone_gain_preference"];
- }
+ [self setBool:lp_config_get_int(conf, LINPHONERC_APPLICATION_KEY, "pushnotification_preference", 0) forKey:@"pushnotification_preference"];
{
- int port = lp_config_get_int(conf, LINPHONERC_APPLICATION_KEY, "port_preference", 5060);
- [self setInteger:port forKey:@"port_preference"];
- int random_port_preference = lp_config_get_int(conf,LINPHONERC_APPLICATION_KEY,"random_port_preference", 1);
- [self setInteger:random_port_preference forKey:@"random_port_preference"];
+ LinphoneAddress *parsed = linphone_core_get_primary_contact_parsed(lc);
+ if(parsed != NULL) {
+ [self setString: linphone_address_get_display_name(parsed) forKey:@"primary_displayname_preference"];
+ [self setString: linphone_address_get_username(parsed) forKey:@"primary_username_preference"];
+ }
+ linphone_address_destroy(parsed);
+ }
+ {
+ {
+ int minPort, maxPort;
+ linphone_core_get_audio_port_range(lc, &minPort, &maxPort);
+ if(minPort != maxPort)
+ [self setObject:[NSString stringWithFormat:@"%d-%d", minPort, maxPort] forKey:@"audio_port_preference"];
+ else
+ [self setObject:[NSString stringWithFormat:@"%d", minPort] forKey:@"audio_port_preference"];
+ }
+ {
+ int minPort, maxPort;
+ linphone_core_get_video_port_range(lc, &minPort, &maxPort);
+ if(minPort != maxPort)
+ [self setObject:[NSString stringWithFormat:@"%d-%d", minPort, maxPort] forKey:@"video_port_preference"];
+ else
+ [self setObject:[NSString stringWithFormat:@"%d", minPort] forKey:@"video_port_preference"];
+ }
+ }
+ {
+ [self setInteger: linphone_core_get_upload_bandwidth(lc) forKey:@"upload_bandwidth_preference"];
+ [self setInteger: linphone_core_get_download_bandwidth(lc) forKey:@"download_bandwidth_preference"];
+ }
+ {
+ [self setFloat:linphone_core_get_playback_gain_db(lc) forKey:@"playback_gain_preference"];
+ [self setFloat:linphone_core_get_mic_gain_db(lc) forKey:@"microphone_gain_preference"];
+ }
+ {
+ int port = lp_config_get_int(conf, LINPHONERC_APPLICATION_KEY, "port_preference", 5060);
+ [self setInteger:port forKey:@"port_preference"];
+ int random_port_preference = lp_config_get_int(conf,LINPHONERC_APPLICATION_KEY,"random_port_preference", 1);
+ [self setInteger:random_port_preference forKey:@"random_port_preference"];
}
{
LinphoneAuthInfo *ai;
@@ -173,25 +173,28 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
if (elem && (ai=(LinphoneAuthInfo*)elem->data)){
[self setString: linphone_auth_info_get_passwd(ai) forKey:@"password_preference"];
[self setString: linphone_auth_info_get_ha1(ai) forKey:@"ha1_preference"]; // hidden but useful if provisioned
- [self setString:linphone_auth_info_get_userid(ai) forKey:@"userid_preference"];
+ [self setString:linphone_auth_info_get_userid(ai) forKey:@"userid_preference"];
}
}
{
[self setString: linphone_core_get_stun_server(lc) forKey:@"stun_preference"];
- [self setBool:linphone_core_get_firewall_policy(lc)==LinphonePolicyUseIce forKey:@"ice_preference"];
+ [self setBool:linphone_core_get_firewall_policy(lc)==LinphonePolicyUseIce forKey:@"ice_preference"];
}
-
+
{
[self transformCodecsToKeys: linphone_core_get_audio_codecs(lc)];
[self transformCodecsToKeys: linphone_core_get_video_codecs(lc)];
- [self setBool:linphone_core_adaptive_rate_control_enabled(lc) forKey:@"adaptive_rate_control_preference"];
- [self setInteger:lp_config_get_int(conf, "audio", "codec_bitrate_limit", kLinphoneAudioVbrCodecDefaultBitrate) forKey:@"audio_codec_bitrate_limit_preference"];
-
+ [self setBool:linphone_core_adaptive_rate_control_enabled(lc) forKey:@"adaptive_rate_control_preference"];
+ [self setString:linphone_core_get_adaptive_rate_algorithm(lc) forKey:@"adaptive_rate_algorithm_preference"];
+
+ [self setInteger:lp_config_get_int(conf, "audio", "codec_bitrate_limit", kLinphoneAudioVbrCodecDefaultBitrate) forKey:@"audio_codec_bitrate_limit_preference"];
+ [self setInteger:lp_config_get_int(conf, LINPHONERC_APPLICATION_KEY, "voiceproc_preference", 1) forKey:@"voiceproc_preference"];
+ [self setInteger:lp_config_get_int(conf, "sound", "eq_active", 0) forKey:@"eq_active"];
}
- [self setBool:lp_config_get_int(conf, LINPHONERC_APPLICATION_KEY, "advanced_account_preference", 0) forKey:@"advanced_account_preference"];
+ [self setBool:lp_config_get_int(conf, LINPHONERC_APPLICATION_KEY, "advanced_account_preference", 0) forKey:@"advanced_account_preference"];
- {
+ {
LinphoneMediaEncryption menc=linphone_core_get_media_encryption(lc);
const char *val;
switch(menc){
@@ -201,16 +204,16 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
}
[self setString:val forKey:@"media_encryption_preference"];
}
- [self setString: lp_config_get_string(conf, LINPHONERC_APPLICATION_KEY, "rotation_preference", "auto") forKey:@"rotation_preference"];
+ [self setString: lp_config_get_string(conf, LINPHONERC_APPLICATION_KEY, "rotation_preference", "auto") forKey:@"rotation_preference"];
[self setBool: lp_config_get_int(conf, LINPHONERC_APPLICATION_KEY, "edge_opt_preference", 0) forKey:@"edge_opt_preference"];
- [self setBool: lp_config_get_int(conf, LINPHONERC_APPLICATION_KEY, "enable_first_login_view_preference", 0) forKey:@"enable_first_login_view_preference"];
+ [self setBool: lp_config_get_int(conf, LINPHONERC_APPLICATION_KEY, "enable_first_login_view_preference", 0) forKey:@"enable_first_login_view_preference"];
[self setBool: lp_config_get_int(conf, LINPHONERC_APPLICATION_KEY, "debugenable_preference", 0) forKey:@"debugenable_preference"];
[self setBool: lp_config_get_int(conf, LINPHONERC_APPLICATION_KEY, "animations_preference", 1) forKey:@"animations_preference"];
[self setBool: lp_config_get_int(conf, LINPHONERC_APPLICATION_KEY, "wifi_only_preference", 0) forKey:@"wifi_only_preference"];
[self setString: lp_config_get_string(conf, LINPHONERC_APPLICATION_KEY, "sharing_server_preference", NULL) forKey:@"sharing_server_preference"];
- [self setBool:lp_config_get_int(conf, "sip", "use_ipv6", 0) forKey:@"use_ipv6"];
+ [self setBool:lp_config_get_int(conf, "sip", "use_ipv6", 0) forKey:@"use_ipv6"];
+
-
[self setBool: lp_config_get_int(conf,LINPHONERC_APPLICATION_KEY,"start_at_boot_preference",1) forKey:@"start_at_boot_preference"];
[self setBool: lp_config_get_int(conf,LINPHONERC_APPLICATION_KEY,"backgroundmode_preference",1) forKey:@"backgroundmode_preference"];
[self setBool: lp_config_get_int(conf,LINPHONERC_APPLICATION_KEY,"autoanswer_notif_preference",1) forKey:@"autoanswer_notif_preference"];
@@ -221,10 +224,10 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
[self setBool: linphone_core_video_enabled(lc) forKey:@"enable_video_preference"];
pol=linphone_core_get_video_policy(lc);
[self setBool:(pol->automatically_initiate) forKey:@"start_video_preference"];
- [self setBool:(pol->automatically_accept) forKey:@"accept_video_preference"];
- [self setBool:linphone_core_self_view_enabled(lc) forKey:@"self_video_preference"];
+ [self setBool:(pol->automatically_accept) forKey:@"accept_video_preference"];
+ [self setBool:linphone_core_self_view_enabled(lc) forKey:@"self_video_preference"];
BOOL previewEnabled=lp_config_get_int(conf,LINPHONERC_APPLICATION_KEY,"preview_preference",1);
- [self setBool:previewEnabled forKey:@"preview_preference"];
+ [self setBool:previewEnabled forKey:@"preview_preference"];
MSVideoSize vsize = linphone_core_get_preferred_video_size(lc);
int index;
if ((vsize.width == MS_VIDEO_SIZE_720P_W) && (vsize.height == MS_VIDEO_SIZE_720P_H)) {
@@ -236,35 +239,35 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
}
[self setInteger:index forKey:@"video_preferred_size_preference"];
}
- {
- [self setBool:linphone_core_get_use_info_for_dtmf(lc) forKey:@"sipinfo_dtmf_preference"];
- [self setBool:linphone_core_get_use_rfc2833_for_dtmf(lc) forKey:@"rfc_dtmf_preference"];
-
- [self setInteger:linphone_core_get_inc_timeout(lc) forKey:@"incoming_call_timeout_preference"];
- [self setInteger:linphone_core_get_in_call_timeout(lc) forKey:@"in_call_timeout_preference"];
- }
-
- // Tunnel
- if (linphone_core_tunnel_available()){
- LinphoneTunnel *tunnel = linphone_core_get_tunnel([LinphoneManager getLc]);
- [self setString:lp_config_get_string(linphone_core_get_config(lc), LINPHONERC_APPLICATION_KEY, "tunnel_mode_preference", "off") forKey:@"tunnel_mode_preference"];
- const MSList* configs = linphone_tunnel_get_servers(tunnel);
- if(configs != NULL) {
- LinphoneTunnelConfig *ltc = (LinphoneTunnelConfig *)configs->data;
- [self setString:linphone_tunnel_config_get_host(ltc) forKey:@"tunnel_address_preference"];
- [self setInteger:linphone_tunnel_config_get_port(ltc) forKey:@"tunnel_port_preference"];
- } else {
- [self setString:"" forKey:@"tunnel_address_preference"];
- [self setInteger:443 forKey:@"tunnel_port_preference"];
- }
- }
-
+ {
+ [self setBool:linphone_core_get_use_info_for_dtmf(lc) forKey:@"sipinfo_dtmf_preference"];
+ [self setBool:linphone_core_get_use_rfc2833_for_dtmf(lc) forKey:@"rfc_dtmf_preference"];
+
+ [self setInteger:linphone_core_get_inc_timeout(lc) forKey:@"incoming_call_timeout_preference"];
+ [self setInteger:linphone_core_get_in_call_timeout(lc) forKey:@"in_call_timeout_preference"];
+ }
+
+ // Tunnel
+ if (linphone_core_tunnel_available()){
+ LinphoneTunnel *tunnel = linphone_core_get_tunnel([LinphoneManager getLc]);
+ [self setString:lp_config_get_string(linphone_core_get_config(lc), LINPHONERC_APPLICATION_KEY, "tunnel_mode_preference", "off") forKey:@"tunnel_mode_preference"];
+ const MSList* configs = linphone_tunnel_get_servers(tunnel);
+ if(configs != NULL) {
+ LinphoneTunnelConfig *ltc = (LinphoneTunnelConfig *)configs->data;
+ [self setString:linphone_tunnel_config_get_host(ltc) forKey:@"tunnel_address_preference"];
+ [self setInteger:linphone_tunnel_config_get_port(ltc) forKey:@"tunnel_port_preference"];
+ } else {
+ [self setString:"" forKey:@"tunnel_address_preference"];
+ [self setInteger:443 forKey:@"tunnel_port_preference"];
+ }
+ }
+
[changedDict release];
changedDict = [[NSMutableDictionary alloc] init];
-
- // Post event
- NSDictionary *eventDic = [NSDictionary dictionaryWithObject:self forKey:@"settings"];
- [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneLogsUpdate object:self userInfo:eventDic];
+
+ // Post event
+ NSDictionary *eventDic = [NSDictionary dictionaryWithObject:self forKey:@"settings"];
+ [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneLogsUpdate object:self userInfo:eventDic];
}
- (void)setObject:(id)value forKey:(NSString *)key {
@@ -273,7 +276,7 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
}
- (id)objectForKey:(NSString*)key {
- return [dict valueForKey:key];
+ return [dict valueForKey:key];
}
- (BOOL)valueChangedForKey:(NSString*)key {
@@ -281,70 +284,70 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
}
- (void)alertAccountError:(NSString*)error {
- UIAlertView* alertview = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Error", nil)
- message:error
- delegate:nil
- cancelButtonTitle:NSLocalizedString(@"OK", nil)
- otherButtonTitles: nil];
- [alertview show];
- [alertview release];
+ UIAlertView* alertview = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Error", nil)
+ message:error
+ delegate:nil
+ cancelButtonTitle:NSLocalizedString(@"OK", nil)
+ otherButtonTitles: nil];
+ [alertview show];
+ [alertview release];
}
- (void)synchronizeAccount {
LinphoneCore *lc = [LinphoneManager getLc];
- LpConfig* conf = linphone_core_get_config(lc);
+ LpConfig* conf = linphone_core_get_config(lc);
LinphoneProxyConfig* proxyCfg = NULL;
BOOL isEditing = FALSE;
- NSString* error = nil;
+ NSString* error = nil;
int port_preference = [self integerForKey:@"port_preference"];
-
- BOOL random_port_preference = [self boolForKey:@"random_port_preference"];
- lp_config_set_int(conf, LINPHONERC_APPLICATION_KEY, "random_port_preference", random_port_preference);
- if(random_port_preference) {
- port_preference = -1;
- }
+
+ BOOL random_port_preference = [self boolForKey:@"random_port_preference"];
+ lp_config_set_int(conf, LINPHONERC_APPLICATION_KEY, "random_port_preference", random_port_preference);
+ if(random_port_preference) {
+ port_preference = -1;
+ }
LCSipTransports transportValue={ port_preference, port_preference, -1, -1 };
- // will also update the sip_*_port section of the config
- if (linphone_core_set_sip_transports(lc, &transportValue)) {
- [LinphoneLogger logc:LinphoneLoggerError format:"cannot set transport"];
- }
+ // will also update the sip_*_port section of the config
+ if (linphone_core_set_sip_transports(lc, &transportValue)) {
+ [LinphoneLogger logc:LinphoneLoggerError format:"cannot set transport"];
+ }
- port_preference = linphone_core_get_sip_port(lc);
- [self setInteger:port_preference forKey:@"port_preference"]; // Update back preference
+ port_preference = linphone_core_get_sip_port(lc);
+ [self setInteger:port_preference forKey:@"port_preference"]; // Update back preference
- BOOL enable_ipv6 = [self boolForKey:@"use_ipv6"];
- lp_config_set_int(conf, "sip", "use_ipv6", enable_ipv6);
- if( linphone_core_ipv6_enabled(lc) != enable_ipv6){
- [LinphoneLogger logc:LinphoneLoggerDebug format:"%@ IPV6", enable_ipv6?@"ENABLING":@"DISABLING"];
- linphone_core_enable_ipv6(lc, enable_ipv6);
- }
+ BOOL enable_ipv6 = [self boolForKey:@"use_ipv6"];
+ lp_config_set_int(conf, "sip", "use_ipv6", enable_ipv6);
+ if( linphone_core_ipv6_enabled(lc) != enable_ipv6){
+ [LinphoneLogger logc:LinphoneLoggerDebug format:"%@ IPV6", enable_ipv6?@"ENABLING":@"DISABLING"];
+ linphone_core_enable_ipv6(lc, enable_ipv6);
+ }
//configure sip account
-
+
//mandatory parameters
NSString* username = [self stringForKey:@"username_preference"];
- NSString* userID = [self stringForKey:@"userid_preference"];
+ NSString* userID = [self stringForKey:@"userid_preference"];
NSString* domain = [self stringForKey:@"domain_preference"];
- NSString* transport = [self stringForKey:@"transport_preference"];
- NSString* accountHa1 = [self stringForKey:@"ha1_preference"];
+ NSString* transport = [self stringForKey:@"transport_preference"];
+ NSString* accountHa1 = [self stringForKey:@"ha1_preference"];
NSString* accountPassword = [self stringForKey:@"password_preference"];
- bool isOutboundProxy = [self boolForKey:@"outbound_proxy_preference"];
- BOOL use_avpf = [self boolForKey:@"avpf_preference"];
+ bool isOutboundProxy = [self boolForKey:@"outbound_proxy_preference"];
+ BOOL use_avpf = [self boolForKey:@"avpf_preference"];
if (username && [username length] >0 && domain && [domain length]>0) {
- int expire = [self integerForKey:@"expire_preference"];
- BOOL isWifiOnly = [self boolForKey:@"wifi_only_preference"];
- BOOL pushnotification = [self boolForKey:@"pushnotification_preference"];
- NSString* prefix = [self stringForKey:@"prefix_preference"];
- NSString* proxyAddress = [self stringForKey:@"proxy_preference"];
+ int expire = [self integerForKey:@"expire_preference"];
+ BOOL isWifiOnly = [self boolForKey:@"wifi_only_preference"];
+ BOOL pushnotification = [self boolForKey:@"pushnotification_preference"];
+ NSString* prefix = [self stringForKey:@"prefix_preference"];
+ NSString* proxyAddress = [self stringForKey:@"proxy_preference"];
- LinphoneAuthInfo *info = NULL;
- const char* route = NULL;
+ LinphoneAuthInfo *info = NULL;
+ const char* route = NULL;
if( isWifiOnly && [LinphoneManager instance].connectivity == wwan ) expire = 0;
@@ -353,19 +356,19 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
} else {
proxyAddress = [NSString stringWithFormat:@"sip:%@",proxyAddress] ;
}
-
+
char* proxy = ms_strdup([proxyAddress cStringUsingEncoding:[NSString defaultCStringEncoding]]);
- LinphoneAddress* proxy_addr = linphone_address_new(proxy);
+ LinphoneAddress* proxy_addr = linphone_address_new(proxy);
- if( proxy_addr ){
- LinphoneTransportType type = LinphoneTransportUdp;
- if ( [transport isEqualToString:@"tcp"] ) type = LinphoneTransportTcp;
- else if ( [transport isEqualToString:@"tls"] ) type = LinphoneTransportTls;
+ if( proxy_addr ){
+ LinphoneTransportType type = LinphoneTransportUdp;
+ if ( [transport isEqualToString:@"tcp"] ) type = LinphoneTransportTcp;
+ else if ( [transport isEqualToString:@"tls"] ) type = LinphoneTransportTls;
- linphone_address_set_transport(proxy_addr, type);
- ms_free(proxy);
- proxy = linphone_address_as_string_uri_only(proxy_addr);
- }
+ linphone_address_set_transport(proxy_addr, type);
+ ms_free(proxy);
+ proxy = linphone_address_as_string_uri_only(proxy_addr);
+ }
// use proxy as route if outbound_proxy is enabled
route = isOutboundProxy? proxy : NULL;
@@ -391,7 +394,7 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
if( linphone_proxy_config_set_identity(proxyCfg, identity) == -1 ) { error = NSLocalizedString(@"Invalid username or domain",nil); goto bad_proxy;}
- if( linphone_proxy_config_set_server_addr(proxyCfg, proxy) == -1 ) { error = NSLocalizedString(@"Invalid proxy address", nil); goto bad_proxy; }
+ if( linphone_proxy_config_set_server_addr(proxyCfg, proxy) == -1 ) { error = NSLocalizedString(@"Invalid proxy address", nil); goto bad_proxy; }
if( linphone_proxy_config_set_route(proxyCfg, route) == -1 ) { error = NSLocalizedString(@"Invalid route", nil); goto bad_proxy; }
if ([prefix length]>0) {
@@ -403,26 +406,26 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
linphone_proxy_config_set_dial_escape_plus(proxyCfg,substitute_plus_by_00);
}
- lp_config_set_int(conf, LINPHONERC_APPLICATION_KEY, "pushnotification_preference", pushnotification);
- if( pushnotification ) [[LinphoneManager instance] addPushTokenToProxyConfig:proxyCfg];
+ lp_config_set_int(conf, LINPHONERC_APPLICATION_KEY, "pushnotification_preference", pushnotification);
+ if( pushnotification ) [[LinphoneManager instance] addPushTokenToProxyConfig:proxyCfg];
- linphone_proxy_config_enable_register(proxyCfg, true);
- linphone_proxy_config_enable_avpf(proxyCfg, use_avpf);
+ linphone_proxy_config_enable_register(proxyCfg, true);
+ linphone_proxy_config_enable_avpf(proxyCfg, use_avpf);
linphone_proxy_config_set_expires(proxyCfg, expire);
// setup auth info
LinphoneAddress *from = linphone_address_new(identity);
if (from != 0){
- const char* userid_str = (userID != nil)? [userID UTF8String] : NULL;
+ const char* userid_str = (userID != nil)? [userID UTF8String] : NULL;
info=linphone_auth_info_new(linphone_address_get_username(from),userid_str,password,ha1,NULL,linphone_proxy_config_get_domain(proxyCfg));
- linphone_address_destroy(from);
+ linphone_address_destroy(from);
}
- // We reached here without hitting the goto: the new settings are correct, so replace the previous ones.
+ // We reached here without hitting the goto: the new settings are correct, so replace the previous ones.
// add auth info
linphone_core_clear_all_auth_info(lc);
- if( info ) { linphone_core_add_auth_info(lc,info); }
+ if( info ) { linphone_core_add_auth_info(lc,info); }
// setup new proxycfg
if( isEditing ){
@@ -433,116 +436,131 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
linphone_core_set_default_proxy(lc,proxyCfg);
}
- bad_proxy:
+ bad_proxy:
if( linphoneAddress)
- linphone_address_destroy(linphoneAddress);
- if( proxy)
- ms_free(proxy);
- if( info )
- linphone_auth_info_destroy(info);
+ linphone_address_destroy(linphoneAddress);
+ if( proxy)
+ ms_free(proxy);
+ if( info )
+ linphone_auth_info_destroy(info);
// in case of error, show an alert to the user
- if( error != nil ){
+ if( error != nil ){
if( isEditing ) linphone_proxy_config_done(proxyCfg);
else linphone_proxy_config_destroy(proxyCfg);
- [self alertAccountError:error];
- }
+ [self alertAccountError:error];
+ }
}
- [[[LinphoneManager instance] fastAddressBook] reload];
+ [[[LinphoneManager instance] fastAddressBook] reload];
}
+ (int)validPort:(int)port {
- if(port < 0) {
- return 0;
- }
- if(port > 65535) {
- return 65535;
- }
- return port;
+ if(port < 0) {
+ return 0;
+ }
+ if(port > 65535) {
+ return 65535;
+ }
+ return port;
}
+ (BOOL)parsePortRange:(NSString*)text minPort:(int*)minPort maxPort:(int*)maxPort {
- NSError* error = nil;
- *minPort = -1;
- *maxPort = -1;
- NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:@"([0-9]+)(([^0-9]+)([0-9]+))?" options:0 error:&error];
- if(error != NULL)
- return FALSE;
- NSArray* matches = [regex matchesInString:text options:0 range:NSMakeRange(0, [text length])];
- if([matches count] == 1) {
- NSTextCheckingResult *match = [matches objectAtIndex:0];
- bool range = [match rangeAtIndex:2].length > 0;
- if(!range) {
- NSRange rangeMinPort = [match rangeAtIndex:1];
- *minPort = [LinphoneCoreSettingsStore validPort:[[text substringWithRange:rangeMinPort] integerValue]];
- *maxPort = *minPort;
- return TRUE;
- } else {
- NSRange rangeMinPort = [match rangeAtIndex:1];
- *minPort = [LinphoneCoreSettingsStore validPort:[[text substringWithRange:rangeMinPort] integerValue]];
- NSRange rangeMaxPort = [match rangeAtIndex:4];
- *maxPort = [LinphoneCoreSettingsStore validPort:[[text substringWithRange:rangeMaxPort] integerValue]];
- if(*minPort > *maxPort) {
- *minPort = *maxPort;
- }
- return TRUE;
- }
- }
- return FALSE;
+ NSError* error = nil;
+ *minPort = -1;
+ *maxPort = -1;
+ NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:@"([0-9]+)(([^0-9]+)([0-9]+))?" options:0 error:&error];
+ if(error != NULL)
+ return FALSE;
+ NSArray* matches = [regex matchesInString:text options:0 range:NSMakeRange(0, [text length])];
+ if([matches count] == 1) {
+ NSTextCheckingResult *match = [matches objectAtIndex:0];
+ bool range = [match rangeAtIndex:2].length > 0;
+ if(!range) {
+ NSRange rangeMinPort = [match rangeAtIndex:1];
+ *minPort = [LinphoneCoreSettingsStore validPort:[[text substringWithRange:rangeMinPort] integerValue]];
+ *maxPort = *minPort;
+ return TRUE;
+ } else {
+ NSRange rangeMinPort = [match rangeAtIndex:1];
+ *minPort = [LinphoneCoreSettingsStore validPort:[[text substringWithRange:rangeMinPort] integerValue]];
+ NSRange rangeMaxPort = [match rangeAtIndex:4];
+ *maxPort = [LinphoneCoreSettingsStore validPort:[[text substringWithRange:rangeMaxPort] integerValue]];
+ if(*minPort > *maxPort) {
+ *minPort = *maxPort;
+ }
+ return TRUE;
+ }
+ }
+ return FALSE;
}
- (BOOL)synchronize {
if (![LinphoneManager isLcReady]) return YES;
LinphoneCore *lc=[LinphoneManager getLc];
-
+
BOOL account_changed;
-
- account_changed=[self valueChangedForKey:@"username_preference"]
- || [self valueChangedForKey:@"password_preference"]
- || [self valueChangedForKey:@"domain_preference"]
- || [self valueChangedForKey:@"expire_preference"]
+
+ account_changed=[self valueChangedForKey:@"username_preference"]
+ || [self valueChangedForKey:@"password_preference"]
+ || [self valueChangedForKey:@"domain_preference"]
+ || [self valueChangedForKey:@"expire_preference"]
|| [self valueChangedForKey:@"proxy_preference"]
|| [self valueChangedForKey:@"outbound_proxy_preference"]
|| [self valueChangedForKey:@"transport_preference"]
- || [self valueChangedForKey:@"port_preference"]
- || [self valueChangedForKey:@"random_port_preference"]
+ || [self valueChangedForKey:@"port_preference"]
+ || [self valueChangedForKey:@"random_port_preference"]
|| [self valueChangedForKey:@"prefix_preference"]
|| [self valueChangedForKey:@"substitute_+_by_00_preference"]
- || [self valueChangedForKey:@"use_ipv6"]
- || [self valueChangedForKey:@"avpf_preference"]
- || [self valueChangedForKey:@"pushnotification_preference"];
-
+ || [self valueChangedForKey:@"use_ipv6"]
+ || [self valueChangedForKey:@"avpf_preference"]
+ || [self valueChangedForKey:@"pushnotification_preference"];
+
if (account_changed)
[self synchronizeAccount];
-
+
//Configure Codecs
-
+
PayloadType *pt;
const MSList *elem;
-
+
for (elem=linphone_core_get_audio_codecs(lc);elem!=NULL;elem=elem->next){
pt=(PayloadType*)elem->data;
NSString *pref=[LinphoneManager getPreferenceForCodec:pt->mime_type withRate:pt->clock_rate];
linphone_core_enable_payload_type(lc,pt,[self boolForKey: pref]);
}
-
+
for (elem=linphone_core_get_video_codecs(lc);elem!=NULL;elem=elem->next){
pt=(PayloadType*)elem->data;
NSString *pref=[LinphoneManager getPreferenceForCodec:pt->mime_type withRate:pt->clock_rate];
linphone_core_enable_payload_type(lc,pt,[self boolForKey: pref]);
}
- LpConfig *config = linphone_core_get_config(lc);
- lp_config_set_int(config, "audio", "codec_bitrate_limit", [self integerForKey:@"audio_codec_bitrate_limit_preference"]);
+ LpConfig *config = linphone_core_get_config(lc);
+ lp_config_set_int(config, "audio", "codec_bitrate_limit", [self integerForKey:@"audio_codec_bitrate_limit_preference"]);
[[LinphoneManager instance] configureVbrCodecs];
- linphone_core_enable_adaptive_rate_control(lc, [self boolForKey:@"adaptive_rate_control_preference"]);
-
+ linphone_core_enable_adaptive_rate_control(lc, [self boolForKey:@"adaptive_rate_control_preference"]);
+ linphone_core_set_adaptive_rate_algorithm(lc, [
+ [self stringForKey:@"adaptive_rate_algorithm_preference"] cStringUsingEncoding:[NSString defaultCStringEncoding]
+ ]);
+
+ // Voice processing
+ BOOL voice_processing = [self boolForKey:@"voiceproc_preference"];
+ lp_config_set_int(config, LINPHONERC_APPLICATION_KEY, "voiceproc_preference", voice_processing);
+ NSString* au_device = @"AU: Audio Unit Receiver";
+ 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]);
+
+ BOOL equalizer = [self boolForKey:@"eq_active"];
+ lp_config_set_int(config, "sound", "eq_active", equalizer);
+
linphone_core_set_use_info_for_dtmf(lc, [self boolForKey:@"sipinfo_dtmf_preference"]);
linphone_core_set_use_rfc2833_for_dtmf(lc, [self boolForKey:@"rfc_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"]);
-
+ lp_config_set_string(config, "app", "voice_mail_uri", [[self stringForKey:@"voice_mail_uri_preference"] UTF8String]);
+
bool enableVideo = [self boolForKey:@"enable_video_preference"];
linphone_core_enable_video(lc, enableVideo, enableVideo);
@@ -552,27 +570,27 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
else if (menc && [menc compare:@"ZRTP"] == NSOrderedSame)
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 UTF8String]);
- BOOL ice_preference = [self boolForKey:@"ice_preference"];
- if(ice_preference) {
- linphone_core_set_firewall_policy(lc, LinphonePolicyUseIce);
- } else {
- 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:@"accept_video_preference"];
- policy.automatically_initiate = [self boolForKey:@"start_video_preference"];
- linphone_core_set_video_policy(lc, &policy);
- linphone_core_enable_self_view(lc, [self boolForKey:@"self_video_preference"]);
+ 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 UTF8String]);
+ BOOL ice_preference = [self boolForKey:@"ice_preference"];
+ if(ice_preference) {
+ linphone_core_set_firewall_policy(lc, LinphonePolicyUseIce);
+ } else {
+ 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:@"accept_video_preference"];
+ policy.automatically_initiate = [self boolForKey:@"start_video_preference"];
+ linphone_core_set_video_policy(lc, &policy);
+ linphone_core_enable_self_view(lc, [self boolForKey:@"self_video_preference"]);
BOOL preview_preference=[self boolForKey:@"preview_preference"];
lp_config_set_int(config, LINPHONERC_APPLICATION_KEY, "preview_preference", preview_preference);
MSVideoSize vsize;
@@ -580,13 +598,13 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
switch ([self integerForKey:@"video_preferred_size_preference"]) {
case 0:
MS_VIDEO_SIZE_ASSIGN(vsize, 720P);
- // 128 = margin for audio, the BW includes both video and audio
+ // 128 = margin for audio, the BW includes both video and audio
bw = 1024 + 128;
- break;
+ break;
case 1:
MS_VIDEO_SIZE_ASSIGN(vsize, VGA);
- // no margin for VGA or QVGA, because video encoders can encode the
- // target resulution in less than the asked bandwidth
+ // no margin for VGA or QVGA, because video encoders can encode the
+ // target resulution in less than the asked bandwidth
bw = 512;
break;
case 2:
@@ -598,47 +616,47 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
linphone_core_set_preferred_video_size(lc, vsize);
[self setInteger: bw forKey:@"upload_bandwidth_preference"];
[self setInteger: bw forKey:@"download_bandwidth_preference"];
-
- // Primary contact
- 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 cStringUsingEncoding:[NSString defaultCStringEncoding]]);
- linphone_address_set_username(parsed,[username cStringUsingEncoding:[NSString defaultCStringEncoding]]);
- char *contact = linphone_address_as_string(parsed);
- linphone_core_set_primary_contact(lc, contact);
- ms_free(contact);
- linphone_address_destroy(parsed);
- }
-
- // Audio & Video Port
- {
- 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);
- }
-
- int upload_bandwidth = [self integerForKey:@"upload_bandwidth_preference"];
- linphone_core_set_upload_bandwidth(lc, upload_bandwidth);
-
- int download_bandwidth = [self integerForKey:@"download_bandwidth_preference"];
- linphone_core_set_download_bandwidth(lc, download_bandwidth);
-
- float playback_gain = [self floatForKey:@"playback_gain_preference"];
- linphone_core_set_playback_gain_db(lc, playback_gain);
-
- float mic_gain = [self floatForKey:@"microphone_gain_preference"];
- linphone_core_set_mic_gain_db(lc, mic_gain);
-
+ // Primary contact
+ 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 cStringUsingEncoding:[NSString defaultCStringEncoding]]);
+ linphone_address_set_username(parsed,[username cStringUsingEncoding:[NSString defaultCStringEncoding]]);
+ char *contact = linphone_address_as_string(parsed);
+ linphone_core_set_primary_contact(lc, contact);
+ ms_free(contact);
+ linphone_address_destroy(parsed);
+ }
+
+
+ // Audio & Video Port
+ {
+ 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);
+ }
+
+ int upload_bandwidth = [self integerForKey:@"upload_bandwidth_preference"];
+ linphone_core_set_upload_bandwidth(lc, upload_bandwidth);
+
+ int download_bandwidth = [self integerForKey:@"download_bandwidth_preference"];
+ linphone_core_set_download_bandwidth(lc, download_bandwidth);
+
+ float playback_gain = [self floatForKey:@"playback_gain_preference"];
+ linphone_core_set_playback_gain_db(lc, playback_gain);
+
+ float mic_gain = [self floatForKey:@"microphone_gain_preference"];
+ linphone_core_set_mic_gain_db(lc, mic_gain);
+
UIDevice* device = [UIDevice currentDevice];
bool backgroundSupported = false;
if ([device respondsToSelector:@selector(isMultitaskingSupported)])
@@ -652,84 +670,84 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
lp_config_set_int(config, LINPHONERC_APPLICATION_KEY, "backgroundmode_preference", isbackgroundModeEnabled);
lp_config_set_int(config, LINPHONERC_APPLICATION_KEY, "start_at_boot_preference", [self boolForKey:@"start_at_boot_preference"]);
- lp_config_set_int(config, LINPHONERC_APPLICATION_KEY, "autoanswer_notif_preference", [self boolForKey:@"autoanswer_notif_preference"]);
- lp_config_set_int(config, LINPHONERC_APPLICATION_KEY, "advanced_account_preference", [self boolForKey:@"advanced_account_preference"]);
+ lp_config_set_int(config, LINPHONERC_APPLICATION_KEY, "autoanswer_notif_preference", [self boolForKey:@"autoanswer_notif_preference"]);
+ lp_config_set_int(config, LINPHONERC_APPLICATION_KEY, "advanced_account_preference", [self boolForKey:@"advanced_account_preference"]);
+
+ BOOL firstloginview = [self boolForKey:@"enable_first_login_view_preference"];
+ lp_config_set_int(config, LINPHONERC_APPLICATION_KEY, "enable_first_login_view_preference", firstloginview);
+
+ BOOL edgeOpt = [self boolForKey:@"edge_opt_preference"];
+ lp_config_set_int(config, LINPHONERC_APPLICATION_KEY, "edge_opt_preference", edgeOpt);
+
+ NSString *landscape = [self stringForKey:@"rotation_preference"];
+ lp_config_set_string(config, LINPHONERC_APPLICATION_KEY, "rotation_preference", [landscape UTF8String]);
- BOOL firstloginview = [self boolForKey:@"enable_first_login_view_preference"];
- lp_config_set_int(config, LINPHONERC_APPLICATION_KEY, "enable_first_login_view_preference", firstloginview);
-
- BOOL edgeOpt = [self boolForKey:@"edge_opt_preference"];
- lp_config_set_int(config, LINPHONERC_APPLICATION_KEY, "edge_opt_preference", edgeOpt);
-
- NSString *landscape = [self stringForKey:@"rotation_preference"];
- lp_config_set_string(config, LINPHONERC_APPLICATION_KEY, "rotation_preference", [landscape UTF8String]);
-
BOOL debugmode = [self boolForKey:@"debugenable_preference"];
lp_config_set_int(config, LINPHONERC_APPLICATION_KEY, "debugenable_preference", debugmode);
if (debugmode) {
- linphone_core_enable_logs_with_cb((OrtpLogFunc)linphone_iphone_log_handler);
- ortp_set_log_level_mask(ORTP_DEBUG|ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL);
- } else {
- linphone_core_disable_logs();
- }
-
- BOOL animations = [self boolForKey:@"animations_preference"];
+ linphone_core_enable_logs_with_cb((OrtpLogFunc)linphone_iphone_log_handler);
+ ortp_set_log_level_mask(ORTP_DEBUG|ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL);
+ } else {
+ linphone_core_disable_logs();
+ }
+
+ BOOL animations = [self boolForKey:@"animations_preference"];
lp_config_set_int(config, LINPHONERC_APPLICATION_KEY, "animations_preference", animations);
-
- BOOL wifiOnly = [self boolForKey:@"wifi_only_preference"];
+
+ BOOL wifiOnly = [self boolForKey:@"wifi_only_preference"];
lp_config_set_int(config, LINPHONERC_APPLICATION_KEY, "wifi_only_preference", wifiOnly);
- if([self valueChangedForKey:@"wifi_only_preference"]) {
- [[LinphoneManager instance] setupNetworkReachabilityCallback];
- }
-
+ if([self valueChangedForKey:@"wifi_only_preference"]) {
+ [[LinphoneManager instance] setupNetworkReachabilityCallback];
+ }
+
NSString* sharing_server = [self stringForKey:@"sharing_server_preference"];
[[LinphoneManager instance] lpConfigSetString:sharing_server forKey:@"sharing_server_preference"];
-
-
- //Tunnel
- 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([LinphoneManager getLc]);
- TunnelMode mode = tunnel_off;
- 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);
-
- if ([lTunnelPrefMode isEqualToString:@"off"]) {
- mode = tunnel_off;
- } else if ([lTunnelPrefMode isEqualToString:@"on"]) {
- mode = tunnel_on;
- } else if ([lTunnelPrefMode isEqualToString:@"wwan"]) {
- mode = tunnel_wwan;
- } else if ([lTunnelPrefMode isEqualToString:@"auto"]) {
- mode = tunnel_auto;
- } else {
- [LinphoneLogger logc:LinphoneLoggerError format:"Unexpected tunnel mode [%s]",[lTunnelPrefMode cStringUsingEncoding:[NSString defaultCStringEncoding]]];
- }
- }
-
- lp_config_set_string(linphone_core_get_config(lc), LINPHONERC_APPLICATION_KEY, "tunnel_mode_preference", [lTunnelPrefMode UTF8String]);
- [[LinphoneManager instance] setTunnelMode:mode];
- }
-
+
+
+ //Tunnel
+ 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([LinphoneManager getLc]);
+ TunnelMode mode = tunnel_off;
+ 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);
+
+ if ([lTunnelPrefMode isEqualToString:@"off"]) {
+ mode = tunnel_off;
+ } else if ([lTunnelPrefMode isEqualToString:@"on"]) {
+ mode = tunnel_on;
+ } else if ([lTunnelPrefMode isEqualToString:@"wwan"]) {
+ mode = tunnel_wwan;
+ } else if ([lTunnelPrefMode isEqualToString:@"auto"]) {
+ mode = tunnel_auto;
+ } else {
+ [LinphoneLogger logc:LinphoneLoggerError format:"Unexpected tunnel mode [%s]",[lTunnelPrefMode cStringUsingEncoding:[NSString defaultCStringEncoding]]];
+ }
+ }
+
+ lp_config_set_string(linphone_core_get_config(lc), LINPHONERC_APPLICATION_KEY, "tunnel_mode_preference", [lTunnelPrefMode UTF8String]);
+ [[LinphoneManager instance] setTunnelMode:mode];
+ }
+
[changedDict release];
changedDict = [[NSMutableDictionary alloc] init];
-
- // Post event
- NSDictionary *eventDic = [NSDictionary dictionaryWithObject:self forKey:@"settings"];
- [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneSettingsUpdate object:self userInfo:eventDic];
-
- return YES;
+
+ // Post event
+ NSDictionary *eventDic = [NSDictionary dictionaryWithObject:self forKey:@"settings"];
+ [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneSettingsUpdate object:self userInfo:eventDic];
+
+ return YES;
}
@end
diff --git a/Classes/LinphoneManager.h b/Classes/LinphoneManager.h
index 6fa0e1fd7..ab76faeec 100644
--- a/Classes/LinphoneManager.h
+++ b/Classes/LinphoneManager.h
@@ -4,18 +4,18 @@
*
* 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
+ * 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.
- */
+ */
#import
#import
@@ -50,6 +50,7 @@ extern NSString *const kLinphoneSettingsUpdate;
extern NSString *const kLinphoneBluetoothAvailabilityUpdate;
extern NSString *const kLinphoneConfiguringStateUpdate;
extern NSString *const kLinphoneGlobalStateUpdate;
+extern NSString *const kLinphoneNotifyReceived;
typedef enum _NetworkType {
network_none = 0,
@@ -105,7 +106,7 @@ typedef struct _LinphoneManagerSounds {
@interface LinphoneManager : NSObject {
@protected
SCNetworkReachabilityRef proxyReachability;
-
+
@private
NSTimer* mIterateTimer;
NSMutableArray* pendindCallIdFromRemoteNotif;
@@ -174,7 +175,7 @@ typedef struct _LinphoneManagerSounds {
- (NSInteger)lpConfigIntForKey:(NSString*)key;
- (void)lpConfigSetInt:(NSInteger)value forKey:(NSString*)key forSection:(NSString*)section;
- (NSInteger)lpConfigIntForKey:(NSString*)key forSection:(NSString*)section;
-- (void)lpConfigSetBool:(BOOL)value forKey:(NSString*)key;
+- (void)lpConfigSetBool:(BOOL)value forKey:(NSString*)key;
- (BOOL)lpConfigBoolForKey:(NSString*)key;
- (void)lpConfigSetBool:(BOOL)value forKey:(NSString*)key forSection:(NSString*)section;
- (BOOL)lpConfigBoolForKey:(NSString*)key forSection:(NSString*)section;
diff --git a/Classes/LinphoneManager.m b/Classes/LinphoneManager.m
index 6e759060d..2c466a544 100644
--- a/Classes/LinphoneManager.m
+++ b/Classes/LinphoneManager.m
@@ -5,18 +5,18 @@
*
* 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
+ * 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
#include
@@ -38,11 +38,11 @@
#define LINPHONE_LOGS_MAX_ENTRY 5000
static void audioRouteChangeListenerCallback (
- void *inUserData, // 1
- AudioSessionPropertyID inPropertyID, // 2
- UInt32 inPropertyValueSize, // 3
- const void *inPropertyValue // 4
- );
+ void *inUserData, // 1
+ AudioSessionPropertyID inPropertyID, // 2
+ UInt32 inPropertyValueSize, // 3
+ const void *inPropertyValue // 4
+ );
static LinphoneCore* theLinphoneCore = nil;
static LinphoneManager* theLinphoneManager = nil;
@@ -61,6 +61,7 @@ NSString *const kLinphoneSettingsUpdate = @"LinphoneSettingsUpdate";
NSString *const kLinphoneBluetoothAvailabilityUpdate = @"LinphoneBluetoothAvailabilityUpdate";
NSString *const kLinphoneConfiguringStateUpdate = @"LinphoneConfiguringStateUpdate";
NSString *const kLinphoneGlobalStateUpdate = @"LinphoneGlobalStateUpdate";
+NSString *const kLinphoneNotifyReceived = @"LinphoneNotifyReceived";
const int kLinphoneAudioVbrCodecDefaultBitrate=36; /*you can override this from linphonerc or linphonerc-factory*/
@@ -81,11 +82,11 @@ NSString *const kLinphoneInternalChatDBFilename = @"linphone_chats.db";
@implementation LinphoneCallAppData
- (id)init {
- if ((self = [super init])) {
+ if ((self = [super init])) {
self->batteryWarningShown = FALSE;
- self->notification = nil;
+ self->notification = nil;
self->videoRequested = FALSE;
- self->userInfos = [[NSMutableDictionary alloc] init];
+ self->userInfos = [[NSMutableDictionary alloc] init];
}
return self;
}
@@ -116,9 +117,9 @@ NSString *const kLinphoneInternalChatDBFilename = @"linphone_chats.db";
@synthesize configDb;
struct codec_name_pref_table{
- const char *name;
- int rate;
- NSString *prefname;
+ const char *name;
+ int rate;
+ NSString *prefname;
};
struct codec_name_pref_table codec_pref_table[]={
@@ -127,7 +128,7 @@ struct codec_name_pref_table codec_pref_table[]={
{ "silk", 24000, @"silk_24k_preference" },
{ "silk", 16000, @"silk_16k_preference" },
{ "amr", 8000, @"amr_preference" },
- { "gsm", 8000, @"gsm_preference" },
+ { "gsm", 8000, @"gsm_preference" },
{ "ilbc", 8000, @"ilbc_preference"},
{ "pcmu", 8000, @"pcmu_preference"},
{ "pcma", 8000, @"pcma_preference"},
@@ -152,37 +153,37 @@ struct codec_name_pref_table codec_pref_table[]={
}
+ (NSSet *)unsupportedCodecs {
- NSMutableSet *set = [NSMutableSet set];
+ NSMutableSet *set = [NSMutableSet set];
for(int i=0;codec_pref_table[i].name!=NULL;++i) {
- PayloadType* available = linphone_core_find_payload_type(theLinphoneCore,
- codec_pref_table[i].name,
- codec_pref_table[i].rate,
- LINPHONE_FIND_PAYLOAD_IGNORE_CHANNELS);
+ PayloadType* available = linphone_core_find_payload_type(theLinphoneCore,
+ codec_pref_table[i].name,
+ codec_pref_table[i].rate,
+ LINPHONE_FIND_PAYLOAD_IGNORE_CHANNELS);
- if( (available == NULL)
- // these two codecs should not be hidden, even if not supported
- && ![codec_pref_table[i].prefname isEqualToString:@"h264_preference"]
- && ![codec_pref_table[i].prefname isEqualToString:@"mp4v-es_preference"]
- )
- {
- [set addObject:codec_pref_table[i].prefname];
+ if( (available == NULL)
+ // these two codecs should not be hidden, even if not supported
+ && ![codec_pref_table[i].prefname isEqualToString:@"h264_preference"]
+ && ![codec_pref_table[i].prefname isEqualToString:@"mp4v-es_preference"]
+ )
+ {
+ [set addObject:codec_pref_table[i].prefname];
}
}
return set;
}
+ (BOOL)isCodecSupported: (const char *)codecName {
- return (codecName != NULL) &&
- (NULL != linphone_core_find_payload_type(theLinphoneCore, codecName,
- LINPHONE_FIND_PAYLOAD_IGNORE_RATE,
- LINPHONE_FIND_PAYLOAD_IGNORE_CHANNELS));
+ return (codecName != NULL) &&
+ (NULL != linphone_core_find_payload_type(theLinphoneCore, codecName,
+ LINPHONE_FIND_PAYLOAD_IGNORE_RATE,
+ LINPHONE_FIND_PAYLOAD_IGNORE_CHANNELS));
}
+ (BOOL)runningOnIpad {
#ifdef UI_USER_INTERFACE_IDIOM
- return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
+ return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
#else
- return NO;
+ return NO;
#endif
}
@@ -197,84 +198,84 @@ struct codec_name_pref_table codec_pref_table[]={
sysctlbyname("hw.machine", machine, &size, NULL, 0);
NSString *platform = [[NSString alloc ] initWithUTF8String:machine];
free(machine);
-
+
result = ![platform isEqualToString:@"iPhone1,2"];
-
+
[platform release];
done=TRUE;
}
- return result;
+ return result;
}
+ (NSString *)getUserAgent {
- return [NSString stringWithFormat:@"LinphoneIphone/%@ (Linphone/%s; Apple %@/%@)",
- [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString*)kCFBundleVersionKey],
- linphone_core_get_version(),
- [UIDevice currentDevice].systemName,
- [UIDevice currentDevice].systemVersion];
+ return [NSString stringWithFormat:@"LinphoneIphone/%@ (Linphone/%s; Apple %@/%@)",
+ [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString*)kCFBundleVersionKey],
+ linphone_core_get_version(),
+ [UIDevice currentDevice].systemName,
+ [UIDevice currentDevice].systemVersion];
}
+ (LinphoneManager*)instance {
- if(theLinphoneManager == nil) {
- theLinphoneManager = [LinphoneManager alloc];
- [theLinphoneManager init];
- }
+ if(theLinphoneManager == nil) {
+ theLinphoneManager = [LinphoneManager alloc];
+ [theLinphoneManager init];
+ }
return theLinphoneManager;
}
#ifdef DEBUG
+ (void)instanceRelease {
- if(theLinphoneManager != nil) {
- [theLinphoneManager release];
- theLinphoneManager = nil;
- }
+ if(theLinphoneManager != nil) {
+ [theLinphoneManager release];
+ theLinphoneManager = nil;
+ }
}
#endif
#pragma mark - Lifecycle Functions
- (id)init {
- if ((self = [super init])) {
- AudioSessionInitialize(NULL, NULL, NULL, NULL);
- OSStatus lStatus = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, audioRouteChangeListenerCallback, self);
- if (lStatus) {
- [LinphoneLogger logc:LinphoneLoggerError format:"cannot register route change handler [%ld]",lStatus];
- }
-
- // Sounds
- {
- NSString *path = [[NSBundle mainBundle] pathForResource:@"ring" ofType:@"wav"];
- sounds.call = 0;
- OSStatus status = AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:path], &sounds.call);
- if(status != 0){
- [LinphoneLogger log:LinphoneLoggerWarning format:@"Can't set \"call\" system sound"];
- }
- }
- {
- NSString *path = [[NSBundle mainBundle] pathForResource:@"msg" ofType:@"wav"];
- sounds.message = 0;
- OSStatus status = AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:path], &sounds.message);
- if(status != 0){
- [LinphoneLogger log:LinphoneLoggerWarning format:@"Can't set \"message\" system sound"];
- }
- }
- sounds.vibrate = kSystemSoundID_Vibrate;
-
- logs = [[NSMutableArray alloc] init];
- database = NULL;
- speakerEnabled = FALSE;
- bluetoothEnabled = FALSE;
- tunnelMode = FALSE;
- [self copyDefaultSettings];
- pendindCallIdFromRemoteNotif = [[NSMutableArray alloc] init ];
- photoLibrary = [[ALAssetsLibrary alloc] init];
-
+ if ((self = [super init])) {
+ AudioSessionInitialize(NULL, NULL, NULL, NULL);
+ OSStatus lStatus = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, audioRouteChangeListenerCallback, self);
+ if (lStatus) {
+ [LinphoneLogger logc:LinphoneLoggerError format:"cannot register route change handler [%ld]",lStatus];
+ }
+
+ // Sounds
+ {
+ NSString *path = [[NSBundle mainBundle] pathForResource:@"ring" ofType:@"wav"];
+ sounds.call = 0;
+ OSStatus status = AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:path], &sounds.call);
+ if(status != 0){
+ [LinphoneLogger log:LinphoneLoggerWarning format:@"Can't set \"call\" system sound"];
+ }
+ }
+ {
+ NSString *path = [[NSBundle mainBundle] pathForResource:@"msg" ofType:@"wav"];
+ sounds.message = 0;
+ OSStatus status = AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:path], &sounds.message);
+ if(status != 0){
+ [LinphoneLogger log:LinphoneLoggerWarning format:@"Can't set \"message\" system sound"];
+ }
+ }
+ sounds.vibrate = kSystemSoundID_Vibrate;
+
+ logs = [[NSMutableArray alloc] init];
+ database = NULL;
+ speakerEnabled = FALSE;
+ bluetoothEnabled = FALSE;
+ tunnelMode = FALSE;
+ [self copyDefaultSettings];
+ pendindCallIdFromRemoteNotif = [[NSMutableArray alloc] init ];
+ photoLibrary = [[ALAssetsLibrary alloc] init];
+
NSString* factoryConfig = [LinphoneManager bundleFile:[LinphoneManager runningOnIpad]?@"linphonerc-factory~ipad":@"linphonerc-factory"];
NSString *confiFileName = [LinphoneManager documentFile:@".linphonerc"];
configDb=lp_config_new_with_factory([confiFileName cStringUsingEncoding:[NSString defaultCStringEncoding]] , [factoryConfig cStringUsingEncoding:[NSString defaultCStringEncoding]]);
-
- [self migrateFromUserPrefs];
-
+
+ [self migrateFromUserPrefs];
+
//set default values for first boot
if (lp_config_get_string(configDb,LINPHONERC_APPLICATION_KEY,"debugenable_preference",NULL)==NULL){
#ifdef DEBUG
@@ -283,201 +284,201 @@ struct codec_name_pref_table codec_pref_table[]={
[self lpConfigSetBool:FALSE forKey:@"debugenable_preference"];
#endif
}
- }
- return self;
+ }
+ return self;
}
- (void)dealloc {
- if(sounds.call) {
- AudioServicesDisposeSystemSoundID(sounds.call);
- }
- if(sounds.message) {
- AudioServicesDisposeSystemSoundID(sounds.message);
- }
-
- [fastAddressBook release];
- [logs release];
-
- OSStatus lStatus = AudioSessionRemovePropertyListenerWithUserData(kAudioSessionProperty_AudioRouteChange, audioRouteChangeListenerCallback, self);
+ if(sounds.call) {
+ AudioServicesDisposeSystemSoundID(sounds.call);
+ }
+ if(sounds.message) {
+ AudioServicesDisposeSystemSoundID(sounds.message);
+ }
+
+ [fastAddressBook release];
+ [logs release];
+
+ OSStatus lStatus = AudioSessionRemovePropertyListenerWithUserData(kAudioSessionProperty_AudioRouteChange, audioRouteChangeListenerCallback, self);
if (lStatus) {
[LinphoneLogger logc:LinphoneLoggerError format:"cannot un register route change handler [%ld]", lStatus];
}
- [[NSNotificationCenter defaultCenter] removeObserver:self forKeyPath:kLinphoneGlobalStateUpdate];
- [[NSNotificationCenter defaultCenter] removeObserver:self forKeyPath:kLinphoneConfiguringStateUpdate];
+ [[NSNotificationCenter defaultCenter] removeObserver:self forKeyPath:kLinphoneGlobalStateUpdate];
+ [[NSNotificationCenter defaultCenter] removeObserver:self forKeyPath:kLinphoneConfiguringStateUpdate];
- [photoLibrary release];
+ [photoLibrary release];
[pendindCallIdFromRemoteNotif release];
- [super dealloc];
+ [super dealloc];
}
#pragma mark - Database Functions
static int check_should_migrate_images(void* data ,int argc,char** argv,char** cnames){
- *((BOOL*)data) = TRUE;
- return 0;
+ *((BOOL*)data) = TRUE;
+ return 0;
}
- (BOOL)migrateChatDBIfNeeded:(LinphoneCore*)lc {
- sqlite3* newDb;
- char *errMsg;
- NSError* error;
- NSString *oldDbPath = [LinphoneManager documentFile:kLinphoneOldChatDBFilename];
- NSString *newDbPath = [LinphoneManager documentFile:kLinphoneInternalChatDBFilename];
- BOOL shouldMigrate = [[NSFileManager defaultManager] fileExistsAtPath:oldDbPath];
- BOOL shouldMigrateImages = FALSE;
- LinphoneProxyConfig* default_proxy;
- const char* identity = NULL;
- BOOL migrated = FALSE;
- char* attach_stmt = NULL;
+ sqlite3* newDb;
+ char *errMsg;
+ NSError* error;
+ NSString *oldDbPath = [LinphoneManager documentFile:kLinphoneOldChatDBFilename];
+ NSString *newDbPath = [LinphoneManager documentFile:kLinphoneInternalChatDBFilename];
+ BOOL shouldMigrate = [[NSFileManager defaultManager] fileExistsAtPath:oldDbPath];
+ BOOL shouldMigrateImages = FALSE;
+ LinphoneProxyConfig* default_proxy;
+ const char* identity = NULL;
+ BOOL migrated = FALSE;
+ char* attach_stmt = NULL;
- linphone_core_get_default_proxy(lc, &default_proxy);
+ linphone_core_get_default_proxy(lc, &default_proxy);
if( sqlite3_open([newDbPath UTF8String], &newDb) != SQLITE_OK) {
- [LinphoneLogger log:LinphoneLoggerError format:@"Can't open \"%@\" sqlite3 database.", newDbPath];
+ [LinphoneLogger log:LinphoneLoggerError format:@"Can't open \"%@\" sqlite3 database.", newDbPath];
return FALSE;
- }
+ }
- const char* check_appdata = "SELECT url,message FROM history WHERE url LIKE 'assets-library%' OR message LIKE 'assets-library%' LIMIT 1;";
- // will set "needToMigrateImages to TRUE if a result comes by
- sqlite3_exec(newDb, check_appdata, check_should_migrate_images, &shouldMigrateImages, NULL);
- if( !shouldMigrate && !shouldMigrateImages ) {
- sqlite3_close(newDb);
- return FALSE;
- }
+ const char* check_appdata = "SELECT url,message FROM history WHERE url LIKE 'assets-library%' OR message LIKE 'assets-library%' LIMIT 1;";
+ // will set "needToMigrateImages to TRUE if a result comes by
+ sqlite3_exec(newDb, check_appdata, check_should_migrate_images, &shouldMigrateImages, NULL);
+ if( !shouldMigrate && !shouldMigrateImages ) {
+ sqlite3_close(newDb);
+ return FALSE;
+ }
- [LinphoneLogger logc:LinphoneLoggerLog format:"Starting migration procedure"];
+ [LinphoneLogger logc:LinphoneLoggerLog format:"Starting migration procedure"];
- if( shouldMigrate ){
+ if( shouldMigrate ){
- // attach old database to the new one:
- attach_stmt = sqlite3_mprintf("ATTACH DATABASE %Q AS oldchats", [oldDbPath UTF8String]);
- if( sqlite3_exec(newDb, attach_stmt, NULL, NULL, &errMsg) != SQLITE_OK ){
- [LinphoneLogger logc:LinphoneLoggerError format:"Can't attach old chat table, error[%s] ", errMsg];
- sqlite3_free(errMsg);
- goto exit_dbmigration;
- }
+ // attach old database to the new one:
+ attach_stmt = sqlite3_mprintf("ATTACH DATABASE %Q AS oldchats", [oldDbPath UTF8String]);
+ if( sqlite3_exec(newDb, attach_stmt, NULL, NULL, &errMsg) != SQLITE_OK ){
+ [LinphoneLogger logc:LinphoneLoggerError format:"Can't attach old chat table, error[%s] ", errMsg];
+ sqlite3_free(errMsg);
+ goto exit_dbmigration;
+ }
- // migrate old chats to the new db. The iOS stores timestamp in UTC already, so we can directly put it in the 'utc' field and set 'time' to -1
- const char* migration_statement = "INSERT INTO history (localContact,remoteContact,direction,message,utc,read,status,time) "
- "SELECT localContact,remoteContact,direction,message,time,read,state,'-1' FROM oldchats.chat";
+ // migrate old chats to the new db. The iOS stores timestamp in UTC already, so we can directly put it in the 'utc' field and set 'time' to -1
+ const char* migration_statement = "INSERT INTO history (localContact,remoteContact,direction,message,utc,read,status,time) "
+ "SELECT localContact,remoteContact,direction,message,time,read,state,'-1' FROM oldchats.chat";
- if( sqlite3_exec(newDb, migration_statement, NULL, NULL, &errMsg) != SQLITE_OK ){
- [LinphoneLogger logc:LinphoneLoggerError format:"DB migration failed, error[%s] ", errMsg];
- sqlite3_free(errMsg);
- goto exit_dbmigration;
- }
+ if( sqlite3_exec(newDb, migration_statement, NULL, NULL, &errMsg) != SQLITE_OK ){
+ [LinphoneLogger logc:LinphoneLoggerError format:"DB migration failed, error[%s] ", errMsg];
+ sqlite3_free(errMsg);
+ goto exit_dbmigration;
+ }
- // invert direction of old messages, because iOS was storing the direction flag incorrectly
- const char* invert_direction = "UPDATE history SET direction = NOT direction";
- if( sqlite3_exec(newDb, invert_direction, NULL, NULL, &errMsg) != SQLITE_OK){
- [LinphoneLogger log: LinphoneLoggerError format:@"Inverting direction failed, error[%s]", errMsg];
- sqlite3_free(errMsg);
- goto exit_dbmigration;
- }
+ // invert direction of old messages, because iOS was storing the direction flag incorrectly
+ const char* invert_direction = "UPDATE history SET direction = NOT direction";
+ if( sqlite3_exec(newDb, invert_direction, NULL, NULL, &errMsg) != SQLITE_OK){
+ [LinphoneLogger log: LinphoneLoggerError format:@"Inverting direction failed, error[%s]", errMsg];
+ sqlite3_free(errMsg);
+ goto exit_dbmigration;
+ }
- // replace empty from: or to: by the current identity.
- if( default_proxy ){
- identity = linphone_proxy_config_get_identity(default_proxy);
- }
- if( !identity ){
- identity = "sip:unknown@sip.linphone.org";
- }
+ // replace empty from: or to: by the current identity.
+ if( default_proxy ){
+ identity = linphone_proxy_config_get_identity(default_proxy);
+ }
+ if( !identity ){
+ identity = "sip:unknown@sip.linphone.org";
+ }
- char* from_conversion = sqlite3_mprintf("UPDATE history SET localContact = %Q WHERE localContact = ''", identity);
- if( sqlite3_exec(newDb, from_conversion, NULL, NULL, &errMsg) != SQLITE_OK ){
- [LinphoneLogger logc:LinphoneLoggerError format:"FROM conversion failed, error[%s] ", errMsg];
- sqlite3_free(errMsg);
- }
- sqlite3_free(from_conversion);
+ char* from_conversion = sqlite3_mprintf("UPDATE history SET localContact = %Q WHERE localContact = ''", identity);
+ if( sqlite3_exec(newDb, from_conversion, NULL, NULL, &errMsg) != SQLITE_OK ){
+ [LinphoneLogger logc:LinphoneLoggerError format:"FROM conversion failed, error[%s] ", errMsg];
+ sqlite3_free(errMsg);
+ }
+ sqlite3_free(from_conversion);
- char* to_conversion = sqlite3_mprintf("UPDATE history SET remoteContact = %Q WHERE remoteContact = ''", identity);
- if( sqlite3_exec(newDb, to_conversion, NULL, NULL, &errMsg) != SQLITE_OK ){
- [LinphoneLogger logc:LinphoneLoggerError format:"DB migration failed, error[%s] ", errMsg];
- sqlite3_free(errMsg);
- }
- sqlite3_free(to_conversion);
-
- }
+ char* to_conversion = sqlite3_mprintf("UPDATE history SET remoteContact = %Q WHERE remoteContact = ''", identity);
+ if( sqlite3_exec(newDb, to_conversion, NULL, NULL, &errMsg) != SQLITE_OK ){
+ [LinphoneLogger logc:LinphoneLoggerError format:"DB migration failed, error[%s] ", errMsg];
+ sqlite3_free(errMsg);
+ }
+ sqlite3_free(to_conversion);
- // local image paths were stored in the 'message' field historically. They were
- // very temporarily stored in the 'url' field, and now we migrated them to a JSON-
- // encoded field. These are the migration steps to migrate them.
+ }
- // move already stored images from the messages to the appdata JSON field
- const char* assetslib_migration = "UPDATE history SET appdata='{\"localimage\":\"'||message||'\"}' , message='' WHERE message LIKE 'assets-library%'";
- if( sqlite3_exec(newDb, assetslib_migration, NULL, NULL, &errMsg) != SQLITE_OK ){
- [LinphoneLogger logc:LinphoneLoggerError format:"Assets-history migration for MESSAGE failed, error[%s] ", errMsg];
- sqlite3_free(errMsg);
- }
+ // local image paths were stored in the 'message' field historically. They were
+ // very temporarily stored in the 'url' field, and now we migrated them to a JSON-
+ // encoded field. These are the migration steps to migrate them.
- // move already stored images from the url to the appdata JSON field
- const char* assetslib_migration_fromurl = "UPDATE history SET appdata='{\"localimage\":\"'||url||'\"}' , url='' WHERE url LIKE 'assets-library%'";
- if( sqlite3_exec(newDb, assetslib_migration_fromurl, NULL, NULL, &errMsg) != SQLITE_OK ){
- [LinphoneLogger logc:LinphoneLoggerError format:"Assets-history migration for URL failed, error[%s] ", errMsg];
- sqlite3_free(errMsg);
- }
+ // move already stored images from the messages to the appdata JSON field
+ const char* assetslib_migration = "UPDATE history SET appdata='{\"localimage\":\"'||message||'\"}' , message='' WHERE message LIKE 'assets-library%'";
+ if( sqlite3_exec(newDb, assetslib_migration, NULL, NULL, &errMsg) != SQLITE_OK ){
+ [LinphoneLogger logc:LinphoneLoggerError format:"Assets-history migration for MESSAGE failed, error[%s] ", errMsg];
+ sqlite3_free(errMsg);
+ }
- // We will lose received messages with remote url, they will be displayed in plain. We can't do much for them..
- migrated = TRUE;
+ // move already stored images from the url to the appdata JSON field
+ const char* assetslib_migration_fromurl = "UPDATE history SET appdata='{\"localimage\":\"'||url||'\"}' , url='' WHERE url LIKE 'assets-library%'";
+ if( sqlite3_exec(newDb, assetslib_migration_fromurl, NULL, NULL, &errMsg) != SQLITE_OK ){
+ [LinphoneLogger logc:LinphoneLoggerError format:"Assets-history migration for URL failed, error[%s] ", errMsg];
+ sqlite3_free(errMsg);
+ }
+
+ // We will lose received messages with remote url, they will be displayed in plain. We can't do much for them..
+ migrated = TRUE;
exit_dbmigration:
- if( attach_stmt ) sqlite3_free(attach_stmt);
+ if( attach_stmt ) sqlite3_free(attach_stmt);
- sqlite3_close(newDb);
+ sqlite3_close(newDb);
- // in any case, we should remove the old chat db
- if( shouldMigrate && ![[NSFileManager defaultManager] removeItemAtPath:oldDbPath error:&error] ){
- [LinphoneLogger logc:LinphoneLoggerError format:"Could not remove old chat DB: %@", error];
- }
+ // in any case, we should remove the old chat db
+ if( shouldMigrate && ![[NSFileManager defaultManager] removeItemAtPath:oldDbPath error:&error] ){
+ [LinphoneLogger logc:LinphoneLoggerError format:"Could not remove old chat DB: %@", error];
+ }
- [LinphoneLogger log:LinphoneLoggerLog format:@"Message storage migration finished: success = %@", migrated ? @"TRUE":@"FALSE"];
- return migrated;
+ [LinphoneLogger log:LinphoneLoggerLog format:@"Message storage migration finished: success = %@", migrated ? @"TRUE":@"FALSE"];
+ return migrated;
}
- (void)migrateFromUserPrefs {
- static const char* migration_flag = "userpref_migration_done";
+ static const char* migration_flag = "userpref_migration_done";
- if( configDb == nil ) return;
+ if( configDb == nil ) return;
- if( lp_config_get_int(configDb, LINPHONERC_APPLICATION_KEY, migration_flag, 0) ){
- Linphone_log(@"UserPrefs migration already performed, skip");
- return;
- }
+ if( lp_config_get_int(configDb, LINPHONERC_APPLICATION_KEY, migration_flag, 0) ){
+ Linphone_log(@"UserPrefs migration already performed, skip");
+ return;
+ }
- NSDictionary* defaults = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation];
- NSArray* defaults_keys = [defaults allKeys];
- NSDictionary* values = @{@"backgroundmode_preference" :@YES,
- @"debugenable_preference" :@NO,
- @"start_at_boot_preference" :@YES};
- BOOL shouldSync = FALSE;
+ NSDictionary* defaults = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation];
+ NSArray* defaults_keys = [defaults allKeys];
+ NSDictionary* values = @{@"backgroundmode_preference" :@YES,
+ @"debugenable_preference" :@NO,
+ @"start_at_boot_preference" :@YES};
+ BOOL shouldSync = FALSE;
- Linphone_log(@"%d user prefs", [defaults_keys count]);
+ Linphone_log(@"%d user prefs", [defaults_keys count]);
- for( NSString* userpref in values ){
- if( [defaults_keys containsObject:userpref] ){
- Linphone_log(@"Migrating %@ from user preferences: %d", userpref, [[defaults objectForKey:userpref] boolValue]);
- lp_config_set_int(configDb, LINPHONERC_APPLICATION_KEY, [userpref UTF8String], [[defaults objectForKey:userpref] boolValue]);
- [[NSUserDefaults standardUserDefaults] removeObjectForKey:userpref];
- shouldSync = TRUE;
- } else if ( lp_config_get_string(configDb, LINPHONERC_APPLICATION_KEY, [userpref UTF8String], NULL) == NULL ){
- // no default value found in our linphonerc, we need to add them
- lp_config_set_int(configDb, LINPHONERC_APPLICATION_KEY, [userpref UTF8String], [[values objectForKey:userpref] boolValue]);
- }
- }
+ for( NSString* userpref in values ){
+ if( [defaults_keys containsObject:userpref] ){
+ Linphone_log(@"Migrating %@ from user preferences: %d", userpref, [[defaults objectForKey:userpref] boolValue]);
+ lp_config_set_int(configDb, LINPHONERC_APPLICATION_KEY, [userpref UTF8String], [[defaults objectForKey:userpref] boolValue]);
+ [[NSUserDefaults standardUserDefaults] removeObjectForKey:userpref];
+ shouldSync = TRUE;
+ } else if ( lp_config_get_string(configDb, LINPHONERC_APPLICATION_KEY, [userpref UTF8String], NULL) == NULL ){
+ // no default value found in our linphonerc, we need to add them
+ lp_config_set_int(configDb, LINPHONERC_APPLICATION_KEY, [userpref UTF8String], [[values objectForKey:userpref] boolValue]);
+ }
+ }
- if( shouldSync ){
- Linphone_log(@"Synchronizing...");
- [[NSUserDefaults standardUserDefaults] synchronize];
- }
- // don't get back here in the future
- lp_config_set_int(configDb, LINPHONERC_APPLICATION_KEY, migration_flag, 1);
+ if( shouldSync ){
+ Linphone_log(@"Synchronizing...");
+ [[NSUserDefaults standardUserDefaults] synchronize];
+ }
+ // don't get back here in the future
+ lp_config_set_int(configDb, LINPHONERC_APPLICATION_KEY, migration_flag, 1);
}
@@ -491,33 +492,33 @@ exit_dbmigration:
}
+ (BOOL)isLcReady {
- return theLinphoneCore != nil;
+ return theLinphoneCore != nil;
}
#pragma mark Debug functions
struct _entry_data {
- const LpConfig* conf;
- const char* section;
+ const LpConfig* conf;
+ const char* section;
};
static void dump_entry(const char* entry, void*data) {
- struct _entry_data *d = (struct _entry_data*)data;
- const char* value = lp_config_get_string(d->conf, d->section, entry, "");
- [LinphoneLogger log:LinphoneLoggerLog format:@"%s=%s", entry, value];
+ struct _entry_data *d = (struct _entry_data*)data;
+ const char* value = lp_config_get_string(d->conf, d->section, entry, "");
+ [LinphoneLogger log:LinphoneLoggerLog format:@"%s=%s", entry, value];
}
static void dump_section(const char* section, void* data){
- [LinphoneLogger log:LinphoneLoggerLog format:@"[%s]", section ];
- struct _entry_data d = {(const LpConfig*)data, section};
- lp_config_for_each_entry((const LpConfig*)data, section, dump_entry, &d);
+ [LinphoneLogger log:LinphoneLoggerLog format:@"[%s]", section ];
+ struct _entry_data d = {(const LpConfig*)data, section};
+ lp_config_for_each_entry((const LpConfig*)data, section, dump_entry, &d);
}
+ (void)dumpLCConfig {
- if (theLinphoneCore ){
+ if (theLinphoneCore ){
LpConfig *conf=[LinphoneManager instance].configDb;
lp_config_for_each_section(conf, dump_section, conf);
- }
+ }
}
@@ -528,33 +529,33 @@ void linphone_iphone_log_handler(int lev, const char *fmt, va_list args){
NSString* format = [[NSString alloc] initWithUTF8String:fmt];
NSLogv(format, args);
// NSString* formatedString = [[NSString alloc] initWithFormat:format arguments:args];
-//
+//
// dispatch_async(dispatch_get_main_queue(), ^{
// if([[LinphoneManager instance].logs count] >= LINPHONE_LOGS_MAX_ENTRY) {
// [[LinphoneManager instance].logs removeObjectAtIndex:0];
// }
// [[LinphoneManager instance].logs addObject:formatedString];
-//
+//
// // Post event
// NSDictionary *dict = [NSDictionary dictionaryWithObject:formatedString forKey:@"log"];
// [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneLogsUpdate object:[LinphoneManager instance] userInfo:dict];
// });
-//
+//
// [formatedString release];
- [format release];
+ [format release];
}
-//Error/warning log handler
+//Error/warning log handler
static void linphone_iphone_log(struct _LinphoneCore * lc, const char * message) {
- NSString* log = [NSString stringWithCString:message encoding:[NSString defaultCStringEncoding]];
+ NSString* log = [NSString stringWithCString:message encoding:[NSString defaultCStringEncoding]];
NSLog(log, NULL);
-
+
// dispatch_async(dispatch_get_main_queue(), ^{
// if([[LinphoneManager instance].logs count] >= LINPHONE_LOGS_MAX_ENTRY) {
// [[LinphoneManager instance].logs removeObjectAtIndex:0];
// }
// [[LinphoneManager instance].logs addObject:log];
-//
+//
// // Post event
// NSDictionary *dict = [NSDictionary dictionaryWithObject:log forKey:@"log"];
// [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneLogsUpdate object:[LinphoneManager instance] userInfo:dict];
@@ -565,83 +566,83 @@ static void linphone_iphone_log(struct _LinphoneCore * lc, const char * message)
#pragma mark - Display Status Functions
- (void)displayStatus:(NSString*) message {
- // Post event
- NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
- message, @"message",
- nil];
- [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneDisplayStatusUpdate object:self userInfo:dict];
+ // Post event
+ NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
+ message, @"message",
+ nil];
+ [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneDisplayStatusUpdate object:self userInfo:dict];
}
static void linphone_iphone_display_status(struct _LinphoneCore * lc, const char * message) {
- NSString* status = [[NSString alloc] initWithCString:message encoding:[NSString defaultCStringEncoding]];
+ NSString* status = [[NSString alloc] initWithCString:message encoding:[NSString defaultCStringEncoding]];
[(LinphoneManager*)linphone_core_get_user_data(lc) displayStatus:status];
- [status release];
+ [status release];
}
#pragma mark - Call State Functions
- (void)localNotifContinue:(NSTimer*) timer {
- UILocalNotification* notif = [timer userInfo];
- if (notif){
+ UILocalNotification* notif = [timer userInfo];
+ if (notif){
[LinphoneLogger log:LinphoneLoggerLog format:@"cancelling/presenting local notif"];
- [[UIApplication sharedApplication] cancelLocalNotification:notif];
- [[UIApplication sharedApplication] presentLocalNotificationNow:notif];
- }
+ [[UIApplication sharedApplication] cancelLocalNotification:notif];
+ [[UIApplication sharedApplication] presentLocalNotificationNow:notif];
+ }
}
- (void)onCall:(LinphoneCall*)call StateChanged:(LinphoneCallState)state withMessage:(const char *)message {
-
+
// Handling wrapper
LinphoneCallAppData* data=(LinphoneCallAppData*)linphone_call_get_user_pointer(call);
if (!data) {
- data = [[LinphoneCallAppData alloc] init];
- linphone_call_set_user_pointer(call, data);
- }
+ data = [[LinphoneCallAppData alloc] init];
+ linphone_call_set_user_pointer(call, data);
+ }
- if (silentPushCompletion) {
+ if (silentPushCompletion) {
- // we were woken up by a silent push. Call the completion handler with NEWDATA
- // so that the push is notified to the user
- [LinphoneLogger log:LinphoneLoggerLog format:@"onCall - handler %p", silentPushCompletion];
- silentPushCompletion(UIBackgroundFetchResultNewData);
- silentPushCompletion = nil;
- }
+ // we were woken up by a silent push. Call the completion handler with NEWDATA
+ // so that the push is notified to the user
+ [LinphoneLogger log:LinphoneLoggerLog format:@"onCall - handler %p", silentPushCompletion];
+ silentPushCompletion(UIBackgroundFetchResultNewData);
+ silentPushCompletion = nil;
+ }
+
+ const LinphoneAddress *addr = linphone_call_get_remote_address(call);
+ NSString* address = nil;
+ if(addr != NULL) {
+ BOOL useLinphoneAddress = true;
+ // contact name
+ char* lAddress = linphone_address_as_string_uri_only(addr);
+ if(lAddress) {
+ NSString *normalizedSipAddress = [FastAddressBook normalizeSipURI:[NSString stringWithUTF8String:lAddress]];
+ ABRecordRef contact = [fastAddressBook getContact:normalizedSipAddress];
+ if(contact) {
+ address = [FastAddressBook getContactDisplayName:contact];
+ useLinphoneAddress = false;
+ }
+ ms_free(lAddress);
+ }
+ if(useLinphoneAddress) {
+ const char* lDisplayName = linphone_address_get_display_name(addr);
+ const char* lUserName = linphone_address_get_username(addr);
+ if (lDisplayName)
+ address = [NSString stringWithUTF8String:lDisplayName];
+ else if(lUserName)
+ address = [NSString stringWithUTF8String:lUserName];
+ }
+ }
+ if(address == nil) {
+ address = @"Unknown";
+ }
- const LinphoneAddress *addr = linphone_call_get_remote_address(call);
- NSString* address = nil;
- if(addr != NULL) {
- BOOL useLinphoneAddress = true;
- // contact name
- char* lAddress = linphone_address_as_string_uri_only(addr);
- if(lAddress) {
- NSString *normalizedSipAddress = [FastAddressBook normalizeSipURI:[NSString stringWithUTF8String:lAddress]];
- ABRecordRef contact = [fastAddressBook getContact:normalizedSipAddress];
- if(contact) {
- address = [FastAddressBook getContactDisplayName:contact];
- useLinphoneAddress = false;
- }
- ms_free(lAddress);
- }
- if(useLinphoneAddress) {
- const char* lDisplayName = linphone_address_get_display_name(addr);
- const char* lUserName = linphone_address_get_username(addr);
- if (lDisplayName)
- address = [NSString stringWithUTF8String:lDisplayName];
- else if(lUserName)
- address = [NSString stringWithUTF8String:lUserName];
- }
- }
- if(address == nil) {
- address = @"Unknown";
- }
-
if (state == LinphoneCallIncomingReceived) {
-
+
/*first step is to re-enable ctcall center*/
CTCallCenter* lCTCallCenter = [[CTCallCenter alloc] init];
-
+
/*should we reject this call ?*/
if ([lCTCallCenter currentCalls]!=nil) {
char *tmp=linphone_call_get_remote_address_as_string(call);
@@ -654,29 +655,30 @@ static void linphone_iphone_display_status(struct _LinphoneCore * lc, const char
return;
}
[lCTCallCenter release];
-
+
if( [[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]
&& [UIApplication sharedApplication].applicationState != UIApplicationStateActive) {
-
+
LinphoneCallLog* callLog=linphone_call_get_call_log(call);
NSString* callId=[NSString stringWithUTF8String:linphone_call_log_get_call_id(callLog)];
-
+
if (![[LinphoneManager instance] shouldAutoAcceptCallForCallId:callId]){
// case where a remote notification is not already received
// Create a new local notification
data->notification = [[UILocalNotification alloc] init];
if (data->notification) {
- data->timer = [NSTimer scheduledTimerWithTimeInterval:4.0 target:self selector:@selector(localNotifContinue:) userInfo:data->notification repeats:TRUE];
+ data->timer = [NSTimer scheduledTimerWithTimeInterval:4.0 target:self selector:@selector(localNotifContinue:) userInfo:data->notification repeats:TRUE];
- data->notification.repeatInterval = 0;
+ data->notification.repeatInterval = 0;
+ data->notification.category = @"incoming_call";
data->notification.alertBody =[NSString stringWithFormat:NSLocalizedString(@"IC_MSG",nil), address];
data->notification.alertAction = NSLocalizedString(@"Answer", nil);
data->notification.soundName = @"shortring.caf";
data->notification.userInfo = @{@"callId": callId, @"timer":[NSNumber numberWithInt:1] };
- data->notification.applicationIconBadgeNumber = 1;
+ data->notification.applicationIconBadgeNumber = 1;
[[UIApplication sharedApplication] presentLocalNotificationNow:data->notification];
-
+
if (!incallBgTask){
incallBgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler: ^{
[LinphoneLogger log:LinphoneLoggerWarning format:@"Call cannot ring any more, too late"];
@@ -684,87 +686,87 @@ static void linphone_iphone_display_status(struct _LinphoneCore * lc, const char
incallBgTask=0;
}];
- [[NSRunLoop currentRunLoop] addTimer:data->timer forMode:NSRunLoopCommonModes];
+ [[NSRunLoop currentRunLoop] addTimer:data->timer forMode:NSRunLoopCommonModes];
}
-
+
}
}
}
}
- // we keep the speaker auto-enabled state in this static so that we don't
- // force-enable it on ICE re-invite if the user disabled it.
- static BOOL speaker_already_enabled = FALSE;
+ // we keep the speaker auto-enabled state in this static so that we don't
+ // force-enable it on ICE re-invite if the user disabled it.
+ static BOOL speaker_already_enabled = FALSE;
- // Disable speaker when no more call
- if ((state == LinphoneCallEnd || state == LinphoneCallError)) {
- speaker_already_enabled = FALSE;
- if(linphone_core_get_calls_nb(theLinphoneCore) == 0) {
- [self setSpeakerEnabled:FALSE];
+ // Disable speaker when no more call
+ if ((state == LinphoneCallEnd || state == LinphoneCallError)) {
+ speaker_already_enabled = FALSE;
+ if(linphone_core_get_calls_nb(theLinphoneCore) == 0) {
+ [self setSpeakerEnabled:FALSE];
[self removeCTCallCenterCb];
- bluetoothAvailable = FALSE;
- bluetoothEnabled = FALSE;
- /*IOS specific*/
- linphone_core_start_dtmf_stream(theLinphoneCore);
+ bluetoothAvailable = FALSE;
+ bluetoothEnabled = FALSE;
+ /*IOS specific*/
+ linphone_core_start_dtmf_stream(theLinphoneCore);
}
if (incallBgTask) {
[[UIApplication sharedApplication] endBackgroundTask:incallBgTask];
incallBgTask=0;
- }
- if(data != nil && data->notification != nil) {
- LinphoneCallLog *log = linphone_call_get_call_log(call);
-
- // cancel local notif if needed
- if( data->timer ){
- [data->timer invalidate];
- data->timer = nil;
- }
- [[UIApplication sharedApplication] cancelLocalNotification:data->notification];
-
- [data->notification release];
- data->notification = nil;
-
- if(log == NULL || linphone_call_log_get_status(log) == LinphoneCallMissed) {
- UILocalNotification *notification = [[UILocalNotification alloc] init];
- notification.repeatInterval = 0;
- notification.alertBody = [NSString stringWithFormat:NSLocalizedString(@"You missed a call from %@", nil), address];
- notification.alertAction = NSLocalizedString(@"Show", nil);
- notification.userInfo = [NSDictionary dictionaryWithObject:[NSString stringWithUTF8String:linphone_call_log_get_call_id(log)] forKey:@"callLog"];
- [[UIApplication sharedApplication] presentLocalNotificationNow:notification];
- [notification release];
- }
-
- }
- }
-
- if(state == LinphoneCallReleased) {
- if(data != NULL) {
- [data release];
- linphone_call_set_user_pointer(call, NULL);
- }
- }
-
- // Enable speaker when video
- if(state == LinphoneCallIncomingReceived ||
- state == LinphoneCallOutgoingInit ||
- state == LinphoneCallConnected ||
- state == LinphoneCallStreamsRunning) {
- if (linphone_call_params_video_enabled(linphone_call_get_current_params(call)) && !speaker_already_enabled) {
- [self setSpeakerEnabled:TRUE];
- speaker_already_enabled = TRUE;
- }
- }
+ }
+ if(data != nil && data->notification != nil) {
+ LinphoneCallLog *log = linphone_call_get_call_log(call);
- if (state == LinphoneCallConnected && !mCallCenter) {
+ // cancel local notif if needed
+ if( data->timer ){
+ [data->timer invalidate];
+ data->timer = nil;
+ }
+ [[UIApplication sharedApplication] cancelLocalNotification:data->notification];
+
+ [data->notification release];
+ data->notification = nil;
+
+ if(log == NULL || linphone_call_log_get_status(log) == LinphoneCallMissed) {
+ UILocalNotification *notification = [[UILocalNotification alloc] init];
+ notification.repeatInterval = 0;
+ notification.alertBody = [NSString stringWithFormat:NSLocalizedString(@"You missed a call from %@", nil), address];
+ notification.alertAction = NSLocalizedString(@"Show", nil);
+ notification.userInfo = [NSDictionary dictionaryWithObject:[NSString stringWithUTF8String:linphone_call_log_get_call_id(log)] forKey:@"callLog"];
+ [[UIApplication sharedApplication] presentLocalNotificationNow:notification];
+ [notification release];
+ }
+
+ }
+ }
+
+ if(state == LinphoneCallReleased) {
+ if(data != NULL) {
+ [data release];
+ linphone_call_set_user_pointer(call, NULL);
+ }
+ }
+
+ // Enable speaker when video
+ if(state == LinphoneCallIncomingReceived ||
+ state == LinphoneCallOutgoingInit ||
+ state == LinphoneCallConnected ||
+ state == LinphoneCallStreamsRunning) {
+ if (linphone_call_params_video_enabled(linphone_call_get_current_params(call)) && !speaker_already_enabled) {
+ [self setSpeakerEnabled:TRUE];
+ speaker_already_enabled = TRUE;
+ }
+ }
+
+ if (state == LinphoneCallConnected && !mCallCenter) {
/*only register CT call center CB for connected call*/
[self setupGSMInteraction];
}
- // Post event
- NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
- [NSValue valueWithPointer:call], @"call",
- [NSNumber numberWithInt:state], @"state",
- [NSString stringWithUTF8String:message], @"message", nil];
- [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneCallUpdate object:self userInfo:dict];
+ // Post event
+ NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSValue valueWithPointer:call], @"call",
+ [NSNumber numberWithInt:state], @"state",
+ [NSString stringWithUTF8String:message], @"message", nil];
+ [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneCallUpdate object:self userInfo:dict];
}
static void linphone_iphone_call_state(LinphoneCore *lc, LinphoneCall* call, LinphoneCallState state,const char* message) {
@@ -780,73 +782,73 @@ static void linphone_iphone_transfer_state_changed(LinphoneCore* lc, LinphoneCal
#pragma mark - Global state change
static void linphone_iphone_global_state_changed(LinphoneCore *lc, LinphoneGlobalState gstate, const char *message) {
- [(LinphoneManager*)linphone_core_get_user_data(lc) onGlobalStateChanged:gstate withMessage:message];
+ [(LinphoneManager*)linphone_core_get_user_data(lc) onGlobalStateChanged:gstate withMessage:message];
}
-(void)onGlobalStateChanged:(LinphoneGlobalState)state withMessage:(const char*)message {
- [LinphoneLogger log:LinphoneLoggerLog format:@"onGlobalStateChanged: %d (message: %s)", state, message];
+ [LinphoneLogger log:LinphoneLoggerLog format:@"onGlobalStateChanged: %d (message: %s)", state, message];
- NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
- [NSNumber numberWithInt:state], @"state",
- [NSString stringWithUTF8String:message?message:""], @"message",
- nil];
+ NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithInt:state], @"state",
+ [NSString stringWithUTF8String:message?message:""], @"message",
+ nil];
- // dispatch the notification asynchronously
- dispatch_async(dispatch_get_main_queue(), ^(void){
- [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneGlobalStateUpdate object:self userInfo:dict];
- });
+ // dispatch the notification asynchronously
+ dispatch_async(dispatch_get_main_queue(), ^(void){
+ [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneGlobalStateUpdate object:self userInfo:dict];
+ });
}
-(void)globalStateChangedNotificationHandler:(NSNotification*)notif {
- if( (LinphoneGlobalState)[[[notif userInfo] valueForKey:@"state"] integerValue] == LinphoneGlobalOn){
- [self finishCoreConfiguration];
- }
+ if( (LinphoneGlobalState)[[[notif userInfo] valueForKey:@"state"] integerValue] == LinphoneGlobalOn){
+ [self finishCoreConfiguration];
+ }
}
#pragma mark - Configuring status changed
static void linphone_iphone_configuring_status_changed(LinphoneCore *lc, LinphoneConfiguringState status, const char *message) {
- [(LinphoneManager*)linphone_core_get_user_data(lc) onConfiguringStatusChanged:status withMessage:message];
+ [(LinphoneManager*)linphone_core_get_user_data(lc) onConfiguringStatusChanged:status withMessage:message];
}
-(void)onConfiguringStatusChanged:(LinphoneConfiguringState)status withMessage:(const char*)message {
- [LinphoneLogger log:LinphoneLoggerLog format:@"onConfiguringStatusChanged: %d (message: %s)", status, message];
+ [LinphoneLogger log:LinphoneLoggerLog format:@"onConfiguringStatusChanged: %d (message: %s)", status, message];
- NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
- [NSNumber numberWithInt:status], @"state",
- [NSString stringWithUTF8String:message?message:""], @"message",
- nil];
+ NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithInt:status], @"state",
+ [NSString stringWithUTF8String:message?message:""], @"message",
+ nil];
- // dispatch the notification asynchronously
- dispatch_async(dispatch_get_main_queue(), ^(void){
- [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneConfiguringStateUpdate object:self userInfo:dict];
- });
+ // dispatch the notification asynchronously
+ dispatch_async(dispatch_get_main_queue(), ^(void){
+ [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneConfiguringStateUpdate object:self userInfo:dict];
+ });
}
-(void)configuringStateChangedNotificationHandler:(NSNotification*)notif {
- if( (LinphoneConfiguringState)[[[notif userInfo] valueForKey:@"state"] integerValue] == LinphoneConfiguringSuccessful){
- wasRemoteProvisioned = TRUE;
- } else {
- wasRemoteProvisioned = FALSE;
- }
+ if( (LinphoneConfiguringState)[[[notif userInfo] valueForKey:@"state"] integerValue] == LinphoneConfiguringSuccessful){
+ wasRemoteProvisioned = TRUE;
+ } else {
+ wasRemoteProvisioned = FALSE;
+ }
}
#pragma mark - Registration State Functions
- (void)onRegister:(LinphoneCore *)lc cfg:(LinphoneProxyConfig*) cfg state:(LinphoneRegistrationState) state message:(const char*) message {
- [LinphoneLogger logc:LinphoneLoggerLog format:"NEW REGISTRATION STATE: '%s' (message: '%s')", linphone_registration_state_to_string(state), message];
-
- // Post event
- NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
- [NSNumber numberWithInt:state], @"state",
- [NSValue valueWithPointer:cfg], @"cfg",
- [NSString stringWithUTF8String:message], @"message",
- nil];
- [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneRegistrationUpdate object:self userInfo:dict];
+ [LinphoneLogger logc:LinphoneLoggerLog format:"NEW REGISTRATION STATE: '%s' (message: '%s')", linphone_registration_state_to_string(state), message];
+
+ // Post event
+ NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithInt:state], @"state",
+ [NSValue valueWithPointer:cfg], @"cfg",
+ [NSString stringWithUTF8String:message], @"message",
+ nil];
+ [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneRegistrationUpdate object:self userInfo:dict];
}
static void linphone_iphone_registration_state(LinphoneCore *lc, LinphoneProxyConfig* cfg, LinphoneRegistrationState state,const char* message) {
@@ -858,73 +860,90 @@ static void linphone_iphone_registration_state(LinphoneCore *lc, LinphoneProxyCo
- (void)onMessageReceived:(LinphoneCore *)lc room:(LinphoneChatRoom *)room message:(LinphoneChatMessage*)msg {
- if (silentPushCompletion) {
+ if (silentPushCompletion) {
- // we were woken up by a silent push. Call the completion handler with NEWDATA
- // so that the push is notified to the user
- [LinphoneLogger log:LinphoneLoggerLog format:@"onMessageReceived - handler %p", silentPushCompletion];
- silentPushCompletion(UIBackgroundFetchResultNewData);
- silentPushCompletion = nil;
- }
-
- if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]
+ // we were woken up by a silent push. Call the completion handler with NEWDATA
+ // so that the push is notified to the user
+ [LinphoneLogger log:LinphoneLoggerLog format:@"onMessageReceived - handler %p", silentPushCompletion];
+ silentPushCompletion(UIBackgroundFetchResultNewData);
+ silentPushCompletion = nil;
+ }
+
+ if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]
&& [UIApplication sharedApplication].applicationState != UIApplicationStateActive) {
-
- const LinphoneAddress* remoteAddress = linphone_chat_message_get_from(msg);
- char* c_address = linphone_address_as_string_uri_only(remoteAddress);
- NSString* address = [NSString stringWithUTF8String:c_address];
- NSString* from_address = [address copy];
- ABRecordRef contact = [fastAddressBook getContact:address];
- if(contact) {
- address = [FastAddressBook getContactDisplayName:contact];
- } else {
- if ([[LinphoneManager instance] lpConfigBoolForKey:@"show_contacts_emails_preference"] == true) {
- LinphoneAddress *linphoneAddress = linphone_address_new([address cStringUsingEncoding:[NSString defaultCStringEncoding]]);
- address = [NSString stringWithUTF8String:linphone_address_get_username(linphoneAddress)];
- linphone_address_destroy(linphoneAddress);
- }
- }
- if(address == nil) {
- address = @"Unknown";
- }
+ const LinphoneAddress* remoteAddress = linphone_chat_message_get_from_address(msg);
+ char* c_address = linphone_address_as_string_uri_only(remoteAddress);
+ NSString* address = [NSString stringWithUTF8String:c_address];
+ NSString* from_address = [address copy];
+
+ ABRecordRef contact = [fastAddressBook getContact:address];
+ if(contact) {
+ address = [FastAddressBook getContactDisplayName:contact];
+ } else {
+ if ([[LinphoneManager instance] lpConfigBoolForKey:@"show_contacts_emails_preference"] == true) {
+ LinphoneAddress *linphoneAddress = linphone_address_new([address cStringUsingEncoding:[NSString defaultCStringEncoding]]);
+ address = [NSString stringWithUTF8String:linphone_address_get_username(linphoneAddress)];
+ linphone_address_destroy(linphoneAddress);
+ }
+ }
+ if(address == nil) {
+ address = @"Unknown";
+ }
// Create a new notification
UILocalNotification* notif = [[[UILocalNotification alloc] init] autorelease];
if (notif) {
- notif.repeatInterval = 0;
- notif.alertBody = [NSString stringWithFormat:NSLocalizedString(@"IM_MSG",nil), address];
- notif.alertAction = NSLocalizedString(@"Show", nil);
- notif.soundName = @"msg.caf";
- notif.userInfo = @{@"from":from_address };
+ notif.repeatInterval = 0;
+ notif.category = @"incoming_msg";
+ notif.alertBody = [NSString stringWithFormat:NSLocalizedString(@"IM_MSG",nil), address];
+ notif.alertAction = NSLocalizedString(@"Show", nil);
+ notif.soundName = @"msg.caf";
+ notif.userInfo = @{@"from":from_address};
+
-
[[UIApplication sharedApplication] presentLocalNotificationNow:notif];
}
- [from_address release];
+ [from_address release];
}
-
- // Post event
- NSDictionary* dict = @{@"room" :[NSValue valueWithPointer:room],
- @"from_address":[NSValue valueWithPointer:linphone_chat_message_get_from(msg)],
- @"message" :[NSValue valueWithPointer:msg]};
- [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneTextReceived object:self userInfo:dict];
+
+ // Post event
+ NSDictionary* dict = @{@"room" :[NSValue valueWithPointer:room],
+ @"from_address":[NSValue valueWithPointer:linphone_chat_message_get_from(msg)],
+ @"message" :[NSValue valueWithPointer:msg]};
+ [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneTextReceived object:self userInfo:dict];
}
static void linphone_iphone_message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *message) {
- [(LinphoneManager*)linphone_core_get_user_data(lc) onMessageReceived:lc room:room message:message];
+ [(LinphoneManager*)linphone_core_get_user_data(lc) onMessageReceived:lc room:room message:message];
}
-#pragma mark - Message composition start
+- (void)onNotifyReceived:(LinphoneCore *)lc event:(LinphoneEvent *)lev notifyEvent:(const char *)notified_event content:(const LinphoneContent *)body {
+ // Post event
+ NSMutableDictionary* dict = [NSMutableDictionary dictionary];
+ [dict setObject:[NSValue valueWithPointer:lev] forKey:@"event"];
+ [dict setObject:[NSString stringWithUTF8String:notified_event] forKey:@"notified_event"];
+ if (body != NULL) {
+ [dict setObject:[NSValue valueWithPointer:body] forKey:@"content"];
+ }
+ [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneNotifyReceived object:self userInfo:dict];
+
+}
+
+static void linphone_iphone_notify_received(LinphoneCore *lc, LinphoneEvent *lev, const char *notified_event, const LinphoneContent *body) {
+ [(LinphoneManager*)linphone_core_get_user_data(lc) onNotifyReceived:lc event:lev notifyEvent:notified_event content:body];
+}
+
+#pragma mark - Message composition start
- (void)onMessageComposeReceived:(LinphoneCore*)core forRoom:(LinphoneChatRoom*)room {
- [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneTextComposeEvent
- object:self
- userInfo:@{@"room":[NSValue valueWithPointer:room]}];
+ [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneTextComposeEvent
+ object:self
+ userInfo:@{@"room":[NSValue valueWithPointer:room]}];
}
static void linphone_iphone_is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room){
- [(LinphoneManager*)linphone_core_get_user_data(lc) onMessageComposeReceived:lc forRoom:room];
+ [(LinphoneManager*)linphone_core_get_user_data(lc) onMessageComposeReceived:lc forRoom:room];
}
@@ -933,16 +952,16 @@ static void linphone_iphone_is_composing_received(LinphoneCore *lc, LinphoneChat
+ (void)kickOffNetworkConnection {
/*start a new thread to avoid blocking the main ui in case of peer host failure*/
- dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
- CFWriteStreamRef writeStream;
- CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"192.168.0.200"/*"linphone.org"*/, 15000, nil, &writeStream);
- CFWriteStreamOpen (writeStream);
- const char* buff="hello";
- CFWriteStreamWrite (writeStream,(const UInt8*)buff,strlen(buff));
- CFWriteStreamClose (writeStream);
- CFRelease(writeStream);
- });
-}
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ CFWriteStreamRef writeStream;
+ CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"192.168.0.200"/*"linphone.org"*/, 15000, nil, &writeStream);
+ CFWriteStreamOpen (writeStream);
+ const char* buff="hello";
+ CFWriteStreamWrite (writeStream,(const UInt8*)buff,strlen(buff));
+ CFWriteStreamClose (writeStream);
+ CFRelease(writeStream);
+ });
+}
static void showNetworkFlags(SCNetworkReachabilityFlags flags){
[LinphoneLogger logc:LinphoneLoggerLog format:"Network connection flags:"];
@@ -974,23 +993,23 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach
LinphoneProxyConfig* proxy;
linphone_core_get_default_proxy(theLinphoneCore, &proxy);
- struct NetworkReachabilityContext* ctx = nilCtx ? ((struct NetworkReachabilityContext*)nilCtx) : 0;
+ struct NetworkReachabilityContext* ctx = nilCtx ? ((struct NetworkReachabilityContext*)nilCtx) : 0;
if ((flags == 0) || (flags & networkDownFlags)) {
linphone_core_set_network_reachable(theLinphoneCore, false);
lLinphoneMgr.connectivity = none;
[LinphoneManager kickOffNetworkConnection];
} else {
- LinphoneTunnel *tunnel = linphone_core_get_tunnel([LinphoneManager getLc]);
+ LinphoneTunnel *tunnel = linphone_core_get_tunnel([LinphoneManager getLc]);
Connectivity newConnectivity;
BOOL isWifiOnly = lp_config_get_int(lLinphoneMgr.configDb, LINPHONERC_APPLICATION_KEY, "wifi_only_preference",FALSE);
- if (!ctx || ctx->testWWan)
- newConnectivity = flags & kSCNetworkReachabilityFlagsIsWWAN ? wwan:wifi;
- else
- newConnectivity = wifi;
+ if (!ctx || ctx->testWWan)
+ newConnectivity = flags & kSCNetworkReachabilityFlagsIsWWAN ? wwan:wifi;
+ else
+ newConnectivity = wifi;
- if (newConnectivity == wwan
- && proxy
- && isWifiOnly
+ if (newConnectivity == wwan
+ && proxy
+ && isWifiOnly
&& (lLinphoneMgr.connectivity == newConnectivity || lLinphoneMgr.connectivity == none)) {
linphone_proxy_config_expires(proxy, 0);
} else if (proxy){
@@ -999,53 +1018,53 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach
linphone_proxy_config_expires(proxy, defaultExpire);
//else keep default value from linphonecore
}
-
+
if (lLinphoneMgr.connectivity != newConnectivity) {
- if (tunnel) linphone_tunnel_reconnect(tunnel);
+ if (tunnel) linphone_tunnel_reconnect(tunnel);
// connectivity has changed
linphone_core_set_network_reachable(theLinphoneCore,false);
if (newConnectivity == wwan && proxy && isWifiOnly) {
linphone_proxy_config_expires(proxy, 0);
- }
+ }
linphone_core_set_network_reachable(theLinphoneCore,true);
linphone_core_iterate(theLinphoneCore);
[LinphoneLogger logc:LinphoneLoggerLog format:"Network connectivity changed to type [%s]",(newConnectivity==wifi?"wifi":"wwan")];
}
lLinphoneMgr.connectivity=newConnectivity;
- switch (lLinphoneMgr.tunnelMode) {
- case tunnel_wwan:
- linphone_tunnel_enable(tunnel,lLinphoneMgr.connectivity == wwan);
- break;
- case tunnel_auto:
- linphone_tunnel_auto_detect(tunnel);
- break;
- default:
- //nothing to do
- break;
- }
+ switch (lLinphoneMgr.tunnelMode) {
+ case tunnel_wwan:
+ linphone_tunnel_enable(tunnel,lLinphoneMgr.connectivity == wwan);
+ break;
+ case tunnel_auto:
+ linphone_tunnel_auto_detect(tunnel);
+ break;
+ default:
+ //nothing to do
+ break;
+ }
}
if (ctx && ctx->networkStateChanged) {
- (*ctx->networkStateChanged)(lLinphoneMgr.connectivity);
- }
+ (*ctx->networkStateChanged)(lLinphoneMgr.connectivity);
+ }
}
}
- (void)setupNetworkReachabilityCallback {
SCNetworkReachabilityContext *ctx=NULL;
- //any internet cnx
+ //any internet cnx
struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;
-
- if (proxyReachability) {
- [LinphoneLogger logc:LinphoneLoggerLog format:"Cancelling old network reachability"];
- SCNetworkReachabilityUnscheduleFromRunLoop(proxyReachability, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
- CFRelease(proxyReachability);
- proxyReachability = nil;
- }
-
- proxyReachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)&zeroAddress);
+
+ if (proxyReachability) {
+ [LinphoneLogger logc:LinphoneLoggerLog format:"Cancelling old network reachability"];
+ SCNetworkReachabilityUnscheduleFromRunLoop(proxyReachability, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
+ CFRelease(proxyReachability);
+ proxyReachability = nil;
+ }
+
+ proxyReachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)&zeroAddress);
if (!SCNetworkReachabilitySetCallback(proxyReachability, (SCNetworkReachabilityCallBack)networkReachabilityCallBack, ctx)){
[LinphoneLogger logc:LinphoneLoggerError format:"Cannot register reachability cb: %s", SCErrorString(SCError())];
@@ -1063,22 +1082,22 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach
}
- (NetworkType)network {
- UIApplication *app = [UIApplication sharedApplication];
- NSArray *subviews = [[[app valueForKey:@"statusBar"] valueForKey:@"foregroundView"] subviews];
- NSNumber *dataNetworkItemView = nil;
-
- for (id subview in subviews) {
- if([subview isKindOfClass:[NSClassFromString(@"UIStatusBarDataNetworkItemView") class]]) {
- dataNetworkItemView = subview;
- break;
- }
- }
- NSNumber *number = (NSNumber*)[dataNetworkItemView valueForKey:@"dataNetworkType"];
- return [number intValue];
+ UIApplication *app = [UIApplication sharedApplication];
+ NSArray *subviews = [[[app valueForKey:@"statusBar"] valueForKey:@"foregroundView"] subviews];
+ NSNumber *dataNetworkItemView = nil;
+
+ for (id subview in subviews) {
+ if([subview isKindOfClass:[NSClassFromString(@"UIStatusBarDataNetworkItemView") class]]) {
+ dataNetworkItemView = subview;
+ break;
+ }
+ }
+ NSNumber *number = (NSNumber*)[dataNetworkItemView valueForKey:@"dataNetworkType"];
+ return [number intValue];
}
-#pragma mark -
+#pragma mark -
static LinphoneCoreVTable linphonec_vtable = {
.show =NULL,
@@ -1094,10 +1113,11 @@ static LinphoneCoreVTable linphonec_vtable = {
.text_received=NULL,
.message_received=linphone_iphone_message_received,
.dtmf_received=NULL,
- .transfer_state_changed=linphone_iphone_transfer_state_changed,
- .is_composing_received = linphone_iphone_is_composing_received,
- .configuring_status = linphone_iphone_configuring_status_changed,
- .global_state_changed = linphone_iphone_global_state_changed
+ .transfer_state_changed=linphone_iphone_transfer_state_changed,
+ .is_composing_received = linphone_iphone_is_composing_received,
+ .configuring_status = linphone_iphone_configuring_status_changed,
+ .global_state_changed = linphone_iphone_global_state_changed,
+ .notify_received = linphone_iphone_notify_received
};
//scheduling loop
@@ -1107,105 +1127,105 @@ static LinphoneCoreVTable linphonec_vtable = {
- (void)audioSessionInterrupted:(NSNotification *)notification
{
- int interruptionType = [notification.userInfo[AVAudioSessionInterruptionTypeKey] intValue];
- if (interruptionType == AVAudioSessionInterruptionTypeBegan) {
- [self beginInterruption];
- } else if (interruptionType == AVAudioSessionInterruptionTypeEnded) {
- [self endInterruption];
- }
+ int interruptionType = [notification.userInfo[AVAudioSessionInterruptionTypeKey] intValue];
+ if (interruptionType == AVAudioSessionInterruptionTypeBegan) {
+ [self beginInterruption];
+ } else if (interruptionType == AVAudioSessionInterruptionTypeEnded) {
+ [self endInterruption];
+ }
}
/** Should be called once per linphone_core_new() */
- (void)finishCoreConfiguration {
//get default config from bundle
- NSString *zrtpSecretsFileName = [LinphoneManager documentFile:@"zrtp_secrets"];
- NSString *chatDBFileName = [LinphoneManager documentFile:kLinphoneInternalChatDBFilename];
- const char* lRootCa = [[LinphoneManager bundleFile:@"rootca.pem"] cStringUsingEncoding:[NSString defaultCStringEncoding]];
+ NSString *zrtpSecretsFileName = [LinphoneManager documentFile:@"zrtp_secrets"];
+ NSString *chatDBFileName = [LinphoneManager documentFile:kLinphoneInternalChatDBFilename];
+ const char* lRootCa = [[LinphoneManager bundleFile:@"rootca.pem"] cStringUsingEncoding:[NSString defaultCStringEncoding]];
- linphone_core_set_user_agent(theLinphoneCore,"LinphoneIPhone",
- [[[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString*)kCFBundleVersionKey] UTF8String]);
+ linphone_core_set_user_agent(theLinphoneCore,"LinphoneIPhone",
+ [[[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString*)kCFBundleVersionKey] UTF8String]);
[_contactSipField release];
_contactSipField = [[self lpConfigStringForKey:@"contact_im_type_value" withDefault:@"SIP"] retain];
fastAddressBook = [[FastAddressBook alloc] init];
- linphone_core_set_root_ca(theLinphoneCore, lRootCa);
+ linphone_core_set_root_ca(theLinphoneCore, lRootCa);
// Set audio assets
const char* lRing = [[LinphoneManager bundleFile:@"ring.wav"] cStringUsingEncoding:[NSString defaultCStringEncoding]];
linphone_core_set_ring(theLinphoneCore, lRing);
const char* lRingBack = [[LinphoneManager bundleFile:@"ringback.wav"] cStringUsingEncoding:[NSString defaultCStringEncoding]];
linphone_core_set_ringback(theLinphoneCore, lRingBack);
- const char* lPlay = [[LinphoneManager bundleFile:@"hold.wav"] cStringUsingEncoding:[NSString defaultCStringEncoding]];
+ const char* lPlay = [[LinphoneManager bundleFile:@"hold.wav"] cStringUsingEncoding:[NSString defaultCStringEncoding]];
linphone_core_set_play_file(theLinphoneCore, lPlay);
linphone_core_set_zrtp_secrets_file(theLinphoneCore, [zrtpSecretsFileName cStringUsingEncoding:[NSString defaultCStringEncoding]]);
- linphone_core_set_chat_database_path(theLinphoneCore, [chatDBFileName cStringUsingEncoding:[NSString defaultCStringEncoding]]);
+ linphone_core_set_chat_database_path(theLinphoneCore, [chatDBFileName cStringUsingEncoding:[NSString defaultCStringEncoding]]);
- // we need to proceed to the migration *after* the chat database was opened, so that we know it is in consistent state
- BOOL migrated = [self migrateChatDBIfNeeded:theLinphoneCore];
- if( migrated ){
- // if a migration was performed, we should reinitialize the chat database
- linphone_core_set_chat_database_path(theLinphoneCore, [chatDBFileName cStringUsingEncoding:[NSString defaultCStringEncoding]]);
- }
+ // we need to proceed to the migration *after* the chat database was opened, so that we know it is in consistent state
+ BOOL migrated = [self migrateChatDBIfNeeded:theLinphoneCore];
+ if( migrated ){
+ // if a migration was performed, we should reinitialize the chat database
+ linphone_core_set_chat_database_path(theLinphoneCore, [chatDBFileName cStringUsingEncoding:[NSString defaultCStringEncoding]]);
+ }
- /* AVPF migration */
- if( [self lpConfigBoolForKey:@"avpf_migration_done" forSection:@"app"] == FALSE ){
- const MSList* proxies = linphone_core_get_proxy_config_list(theLinphoneCore);
- while(proxies){
- LinphoneProxyConfig* proxy = (LinphoneProxyConfig*)proxies->data;
- const char* addr = linphone_proxy_config_get_addr(proxy);
- // we want to enable AVPF for the proxies
- if( addr && strstr(addr, "sip.linphone.org") != 0 ){
- Linphone_log(@"Migrating proxy config to use AVPF");
- linphone_proxy_config_enable_avpf(proxy, TRUE);
- }
- proxies = proxies->next;
- }
- [self lpConfigSetBool:TRUE forKey:@"avpf_migration_done"];
- }
- /* Quality Reporting migration */
- if( [self lpConfigBoolForKey:@"quality_report_migration_done" forSection:@"app"] == FALSE ){
- const MSList* proxies = linphone_core_get_proxy_config_list(theLinphoneCore);
- while(proxies){
- LinphoneProxyConfig* proxy = (LinphoneProxyConfig*)proxies->data;
- const char* addr = linphone_proxy_config_get_addr(proxy);
- // we want to enable quality reporting for the proxies that are on linphone.org
- if( addr && strstr(addr, "sip.linphone.org") != 0 ){
- Linphone_log(@"Migrating proxy config to send quality report");
- linphone_proxy_config_set_quality_reporting_collector(proxy, "sip:voip-metrics@sip.linphone.org");
- linphone_proxy_config_set_quality_reporting_interval(proxy, 180);
- linphone_proxy_config_enable_quality_reporting(proxy, TRUE);
- }
- proxies = proxies->next;
- }
- [self lpConfigSetBool:TRUE forKey:@"quality_report_migration_done"];
- }
+ /* AVPF migration */
+ if( [self lpConfigBoolForKey:@"avpf_migration_done" forSection:@"app"] == FALSE ){
+ const MSList* proxies = linphone_core_get_proxy_config_list(theLinphoneCore);
+ while(proxies){
+ LinphoneProxyConfig* proxy = (LinphoneProxyConfig*)proxies->data;
+ const char* addr = linphone_proxy_config_get_addr(proxy);
+ // we want to enable AVPF for the proxies
+ if( addr && strstr(addr, "sip.linphone.org") != 0 ){
+ Linphone_log(@"Migrating proxy config to use AVPF");
+ linphone_proxy_config_enable_avpf(proxy, TRUE);
+ }
+ proxies = proxies->next;
+ }
+ [self lpConfigSetBool:TRUE forKey:@"avpf_migration_done"];
+ }
+ /* Quality Reporting migration */
+ if( [self lpConfigBoolForKey:@"quality_report_migration_done" forSection:@"app"] == FALSE ){
+ const MSList* proxies = linphone_core_get_proxy_config_list(theLinphoneCore);
+ while(proxies){
+ LinphoneProxyConfig* proxy = (LinphoneProxyConfig*)proxies->data;
+ const char* addr = linphone_proxy_config_get_addr(proxy);
+ // we want to enable quality reporting for the proxies that are on linphone.org
+ if( addr && strstr(addr, "sip.linphone.org") != 0 ){
+ Linphone_log(@"Migrating proxy config to send quality report");
+ linphone_proxy_config_set_quality_reporting_collector(proxy, "sip:voip-metrics@sip.linphone.org");
+ linphone_proxy_config_set_quality_reporting_interval(proxy, 180);
+ linphone_proxy_config_enable_quality_reporting(proxy, TRUE);
+ }
+ proxies = proxies->next;
+ }
+ [self lpConfigSetBool:TRUE forKey:@"quality_report_migration_done"];
+ }
- [self setupNetworkReachabilityCallback];
+ [self setupNetworkReachabilityCallback];
- NSString* path = [LinphoneManager bundleFile:@"nowebcamCIF.jpg"];
- if (path) {
- const char* imagePath = [path cStringUsingEncoding:[NSString defaultCStringEncoding]];
- [LinphoneLogger logc:LinphoneLoggerLog format:"Using '%s' as source image for no webcam", imagePath];
- linphone_core_set_static_picture(theLinphoneCore, imagePath);
- }
+ NSString* path = [LinphoneManager bundleFile:@"nowebcamCIF.jpg"];
+ if (path) {
+ const char* imagePath = [path cStringUsingEncoding:[NSString defaultCStringEncoding]];
+ [LinphoneLogger logc:LinphoneLoggerLog format:"Using '%s' as source image for no webcam", imagePath];
+ linphone_core_set_static_picture(theLinphoneCore, imagePath);
+ }
/*DETECT cameras*/
frontCamId= backCamId=nil;
char** camlist = (char**)linphone_core_get_video_devices(theLinphoneCore);
- for (char* cam = *camlist;*camlist!=NULL;cam=*++camlist) {
- if (strcmp(FRONT_CAM_NAME, cam)==0) {
- frontCamId = cam;
- //great set default cam to front
- linphone_core_set_video_device(theLinphoneCore, cam);
- }
- if (strcmp(BACK_CAM_NAME, cam)==0) {
- backCamId = cam;
- }
+ for (char* cam = *camlist;*camlist!=NULL;cam=*++camlist) {
+ if (strcmp(FRONT_CAM_NAME, cam)==0) {
+ frontCamId = cam;
+ //great set default cam to front
+ linphone_core_set_video_device(theLinphoneCore, cam);
+ }
+ if (strcmp(BACK_CAM_NAME, cam)==0) {
+ backCamId = cam;
+ }
- }
+ }
if (![LinphoneManager isNotIphone3G]){
PayloadType *pt=linphone_core_find_payload_type(theLinphoneCore,"SILK",24000,-1);
@@ -1216,16 +1236,16 @@ static LinphoneCoreVTable linphonec_vtable = {
linphone_core_enable_video(theLinphoneCore, FALSE, FALSE);
}
- [LinphoneLogger logc:LinphoneLoggerWarning format:"Linphone [%s] started on [%s]", linphone_core_get_version(), [[UIDevice currentDevice].model cStringUsingEncoding:[NSString defaultCStringEncoding]]];
-
+ [LinphoneLogger logc:LinphoneLoggerWarning format:"Linphone [%s] started on [%s]", linphone_core_get_version(), [[UIDevice currentDevice].model cStringUsingEncoding:[NSString defaultCStringEncoding]]];
- // Post event
- NSDictionary *dict = [NSDictionary dictionaryWithObject:[NSValue valueWithPointer:theLinphoneCore]
- forKey:@"core"];
- [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneCoreUpdate
- object:[LinphoneManager instance]
- userInfo:dict];
+ // Post event
+ NSDictionary *dict = [NSDictionary dictionaryWithObject:[NSValue valueWithPointer:theLinphoneCore]
+ forKey:@"core"];
+
+ [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneCoreUpdate
+ object:[LinphoneManager instance]
+ userInfo:dict];
}
@@ -1234,54 +1254,29 @@ static BOOL libStarted = FALSE;
- (void)startLibLinphone {
- if ( libStarted ) {
- [LinphoneLogger logc:LinphoneLoggerError format:"Liblinphone is already initialized!"];
- return;
- }
+ if ( libStarted ) {
+ [LinphoneLogger logc:LinphoneLoggerError format:"Liblinphone is already initialized!"];
+ return;
+ }
- libStarted = TRUE;
+ libStarted = TRUE;
connectivity = none;
signal(SIGPIPE, SIG_IGN);
- ms_init(); // Need to initialize mediastreamer2 before loading the plugins
- libmsilbc_init();
-#if defined (HAVE_SILK)
- libmssilk_init();
-#endif
-#ifdef HAVE_AMR
- libmsamr_init(); //load amr plugin if present from the liblinphone sdk
-#endif
-#ifdef HAVE_X264
- libmsx264_init(); //load x264 plugin if present from the liblinphone sdk
-#endif
-#ifdef HAVE_OPENH264
- libmsopenh264_init(); //load openh264 plugin if present from the liblinphone sdk
-#endif
+ // create linphone core
+ [self createLinphoneCore];
+ linphone_core_migrate_to_multi_transport(theLinphoneCore);
-#if HAVE_G729
- libmsbcg729_init(); // load g729 plugin
-#endif
-
- /*to make sure we don't loose debug trace*/
- if ([self lpConfigBoolForKey:@"debugenable_preference"]) {
- linphone_core_enable_logs_with_cb((OrtpLogFunc)linphone_iphone_log_handler);
- ortp_set_log_level_mask(ORTP_DEBUG|ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL);
- }
-
- // create linphone core
- [self createLinphoneCore];
- linphone_core_migrate_to_multi_transport(theLinphoneCore);
-
- //init audio session
+ // init audio session (just getting the instance will init)
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
BOOL bAudioInputAvailable= audioSession.inputAvailable;
NSError* err;
if( ![audioSession setActive:NO error: &err] && err ){
- NSLog(@"audioSession setActive failed: %@", [err description]);
- }
+ NSLog(@"audioSession setActive failed: %@", [err description]);
+ }
if(!bAudioInputAvailable){
UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"No microphone",nil)
message:NSLocalizedString(@"You need to plug a microphone to your device to use this application.",nil)
@@ -1289,46 +1284,72 @@ static BOOL libStarted = FALSE;
cancelButtonTitle:NSLocalizedString(@"Ok",nil)
otherButtonTitles:nil ,nil];
[error show];
- [error release];
+ [error release];
}
- if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]
+ if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]
&& [UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
//go directly to bg mode
[self enterBackgroundMode];
}
-
+
}
- (void)createLinphoneCore {
- if (theLinphoneCore != nil) {
- [LinphoneLogger logc:LinphoneLoggerLog format:"linphonecore is already created"];
- return;
- }
- [LinphoneLogger logc:LinphoneLoggerLog format:"Create linphonecore"];
+ if (theLinphoneCore != nil) {
+ [LinphoneLogger logc:LinphoneLoggerLog format:"linphonecore is already created"];
+ return;
+ }
+ [LinphoneLogger logc:LinphoneLoggerLog format:"Create linphonecore"];
- connectivity=none;
+ connectivity=none;
+
+ ms_init(); // Need to initialize mediastreamer2 before loading the plugins
+
+ libmsilbc_init();
+#if defined (HAVE_SILK)
+ libmssilk_init();
+#endif
+#ifdef HAVE_AMR
+ libmsamr_init(); //load amr plugin if present from the liblinphone sdk
+#endif
+#ifdef HAVE_X264
+ libmsx264_init(); //load x264 plugin if present from the liblinphone sdk
+#endif
+#ifdef HAVE_OPENH264
+ libmsopenh264_init(); //load openh264 plugin if present from the liblinphone sdk
+#endif
+
+#if HAVE_G729
+ libmsbcg729_init(); // load g729 plugin
+#endif
+
+ /*to make sure we don't loose debug trace*/
+ if ([self lpConfigBoolForKey:@"debugenable_preference"]) {
+ linphone_core_enable_logs_with_cb((OrtpLogFunc)linphone_iphone_log_handler);
+ ortp_set_log_level_mask(ORTP_DEBUG|ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL);
+ }
theLinphoneCore = linphone_core_new_with_config (&linphonec_vtable
,configDb
,self /* user_data */);
- /* set the CA file no matter what, since the remote provisioning could be hitting an HTTPS server */
- const char* lRootCa = [[LinphoneManager bundleFile:@"rootca.pem"] cStringUsingEncoding:[NSString defaultCStringEncoding]];
- linphone_core_set_root_ca(theLinphoneCore, lRootCa);
+ /* set the CA file no matter what, since the remote provisioning could be hitting an HTTPS server */
+ const char* lRootCa = [[LinphoneManager bundleFile:@"rootca.pem"] cStringUsingEncoding:[NSString defaultCStringEncoding]];
+ linphone_core_set_root_ca(theLinphoneCore, lRootCa);
- /* The core will call the linphone_iphone_configuring_status_changed callback when the remote provisioning is loaded (or skipped).
- Wait for this to finish the code configuration */
+ /* The core will call the linphone_iphone_configuring_status_changed callback when the remote provisioning is loaded (or skipped).
+ Wait for this to finish the code configuration */
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioSessionInterrupted:) name:AVAudioSessionInterruptionNotification object:nil];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(globalStateChangedNotificationHandler:) name:kLinphoneGlobalStateUpdate object:nil];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(configuringStateChangedNotificationHandler:) name:kLinphoneConfiguringStateUpdate object:nil];
-
- /*call iterate once immediately in order to initiate background connections with sip server, if any */
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioSessionInterrupted:) name:AVAudioSessionInterruptionNotification object:nil];
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(globalStateChangedNotificationHandler:) name:kLinphoneGlobalStateUpdate object:nil];
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(configuringStateChangedNotificationHandler:) name:kLinphoneConfiguringStateUpdate object:nil];
+
+ /*call iterate once immediately in order to initiate background connections with sip server or remote provisioning grab, if any */
linphone_core_iterate(theLinphoneCore);
- // start scheduler
+ // start scheduler
mIterateTimer = [NSTimer scheduledTimerWithTimeInterval:0.02
target:self
selector:@selector(iterate)
@@ -1337,37 +1358,37 @@ static BOOL libStarted = FALSE;
}
- (void)destroyLibLinphone {
- [mIterateTimer invalidate];
+ [mIterateTimer invalidate];
//just in case
[self removeCTCallCenterCb];
-
- [[NSNotificationCenter defaultCenter] removeObserver:self];
+
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
if (theLinphoneCore != nil) { //just in case application terminate before linphone core initialization
- [LinphoneLogger logc:LinphoneLoggerLog format:"Destroy linphonecore"];
+ [LinphoneLogger logc:LinphoneLoggerLog format:"Destroy linphonecore"];
linphone_core_destroy(theLinphoneCore);
theLinphoneCore = nil;
ms_exit(); // Uninitialize mediastreamer2
-
- // Post event
- NSDictionary *dict = [NSDictionary dictionaryWithObject:[NSValue valueWithPointer:theLinphoneCore] forKey:@"core"];
- [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneCoreUpdate object:[LinphoneManager instance] userInfo:dict];
-
- SCNetworkReachabilityUnscheduleFromRunLoop(proxyReachability, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
- if (proxyReachability)
- CFRelease(proxyReachability);
- proxyReachability=nil;
-
- }
- libStarted = FALSE;
+
+ // Post event
+ NSDictionary *dict = [NSDictionary dictionaryWithObject:[NSValue valueWithPointer:theLinphoneCore] forKey:@"core"];
+ [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneCoreUpdate object:[LinphoneManager instance] userInfo:dict];
+
+ SCNetworkReachabilityUnscheduleFromRunLoop(proxyReachability, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
+ if (proxyReachability)
+ CFRelease(proxyReachability);
+ proxyReachability=nil;
+
+ }
+ libStarted = FALSE;
}
- (void) resetLinphoneCore {
- [self destroyLibLinphone];
- [self createLinphoneCore];
+ [self destroyLibLinphone];
+ [self createLinphoneCore];
- // reset network state to trigger a new network connectivity assessment
- linphone_core_set_network_reachable(theLinphoneCore, FALSE);
+ // reset network state to trigger a new network connectivity assessment
+ linphone_core_set_network_reachable(theLinphoneCore, FALSE);
}
static int comp_call_id(const LinphoneCall* call , const char *callid) {
@@ -1379,34 +1400,34 @@ static int comp_call_id(const LinphoneCall* call , const char *callid) {
}
- (void)cancelLocalNotifTimerForCallId:(NSString*)callid {
- //first, make sure this callid is not already involved in a call
+ //first, make sure this callid is not already involved in a call
if ([LinphoneManager isLcReady]) {
MSList* calls = (MSList*)linphone_core_get_calls(theLinphoneCore);
- MSList* call = ms_list_find_custom(calls, (MSCompareFunc)comp_call_id, [callid UTF8String]);
+ MSList* call = ms_list_find_custom(calls, (MSCompareFunc)comp_call_id, [callid UTF8String]);
if (call != NULL) {
- LinphoneCallAppData* data = linphone_call_get_user_pointer((LinphoneCall*)call->data);
- if ( data->timer )
- [data->timer invalidate];
- data->timer = nil;
+ LinphoneCallAppData* data = linphone_call_get_user_pointer((LinphoneCall*)call->data);
+ if ( data->timer )
+ [data->timer invalidate];
+ data->timer = nil;
return;
}
}
}
- (void)acceptCallForCallId:(NSString*)callid {
- //first, make sure this callid is not already involved in a call
+ //first, make sure this callid is not already involved in a call
if ([LinphoneManager isLcReady]) {
MSList* calls = (MSList*)linphone_core_get_calls(theLinphoneCore);
- MSList* call = ms_list_find_custom(calls, (MSCompareFunc)comp_call_id, [callid UTF8String]);
+ MSList* call = ms_list_find_custom(calls, (MSCompareFunc)comp_call_id, [callid UTF8String]);
if (call != NULL) {
- [self acceptCall:(LinphoneCall*)call->data];
+ [self acceptCall:(LinphoneCall*)call->data];
return;
};
}
}
- (void)enableAutoAnswerForCallId:(NSString*) callid {
- //first, make sure this callid is not already involved in a call
+ //first, make sure this callid is not already involved in a call
if ([LinphoneManager isLcReady]) {
MSList* calls = (MSList*)linphone_core_get_calls(theLinphoneCore);
if (ms_list_find_custom(calls, (MSCompareFunc)comp_call_id, [callid UTF8String])) {
@@ -1417,23 +1438,23 @@ static int comp_call_id(const LinphoneCall* call , const char *callid) {
if ([pendindCallIdFromRemoteNotif count] > 10 /*max number of pending notif*/)
[pendindCallIdFromRemoteNotif removeObjectAtIndex:0];
[pendindCallIdFromRemoteNotif addObject:callid];
-
+
}
- (BOOL)shouldAutoAcceptCallForCallId:(NSString*) callId {
- for (NSString* pendingNotif in pendindCallIdFromRemoteNotif) {
+ for (NSString* pendingNotif in pendindCallIdFromRemoteNotif) {
if ([pendingNotif compare:callId] == NSOrderedSame) {
[pendindCallIdFromRemoteNotif removeObject:pendingNotif];
return TRUE;
}
- }
- return FALSE;
+ }
+ return FALSE;
}
- (BOOL)resignActive {
linphone_core_stop_dtmf_stream(theLinphoneCore);
- return YES;
+ return YES;
}
static int comp_call_state_paused (const LinphoneCall* call, const void* param) {
@@ -1452,18 +1473,18 @@ static int comp_call_state_paused (const LinphoneCall* call, const void* param)
LinphoneProxyConfig* proxyCfg;
linphone_core_get_default_proxy(theLinphoneCore, &proxyCfg);
BOOL shouldEnterBgMode=FALSE;
-
+
//handle proxy config if any
if (proxyCfg) {
if ([[LinphoneManager instance] lpConfigBoolForKey:@"backgroundmode_preference"] ||
[[LinphoneManager instance] lpConfigBoolForKey:@"pushnotification_preference"]) {
-
+
//For registration register
[self refreshRegisters];
}
-
+
if ([[LinphoneManager instance] lpConfigBoolForKey:@"backgroundmode_preference"]) {
-
+
//register keepalive
if ([[UIApplication sharedApplication] setKeepAliveTimeout:600/*(NSTimeInterval)linphone_proxy_config_get_expires(proxyCfg)*/
handler:^{
@@ -1481,8 +1502,8 @@ static int comp_call_state_paused (const LinphoneCall* call, const void* param)
linphone_core_iterate(theLinphoneCore);
}
]) {
-
-
+
+
[LinphoneLogger logc:LinphoneLoggerLog format:"keepalive handler succesfully registered"];
} else {
[LinphoneLogger logc:LinphoneLoggerLog format:"keepalive handler cannot be registered"];
@@ -1490,7 +1511,7 @@ static int comp_call_state_paused (const LinphoneCall* call, const void* param)
shouldEnterBgMode=TRUE;
}
}
-
+
LinphoneCall* currentCall = linphone_core_get_current_call(theLinphoneCore);
const MSList* callList = linphone_core_get_calls(theLinphoneCore);
if (!currentCall //no active call
@@ -1508,9 +1529,9 @@ static int comp_call_state_paused (const LinphoneCall* call, const void* param)
linphone_core_iterate(theLinphoneCore);
}
linphone_core_stop_dtmf_stream(theLinphoneCore);
-
+
[LinphoneLogger logc:LinphoneLoggerLog format:"Entering [%s] bg mode",shouldEnterBgMode?"normal":"lite"];
-
+
if (!shouldEnterBgMode ) {
if([[LinphoneManager instance] lpConfigBoolForKey:@"pushnotification_preference"]) {
[LinphoneLogger logc:LinphoneLoggerLog format:"Keeping lc core to handle push"];
@@ -1521,25 +1542,25 @@ static int comp_call_state_paused (const LinphoneCall* call, const void* param)
}
[self destroyLibLinphone];
return NO;
-
+
} else
return YES;
}
- (void)becomeActive {
- [self refreshRegisters];
- if (pausedCallBgTask) {
+ [self refreshRegisters];
+ if (pausedCallBgTask) {
[[UIApplication sharedApplication] endBackgroundTask:pausedCallBgTask];
pausedCallBgTask=0;
}
- if (incallBgTask) {
+ if (incallBgTask) {
[[UIApplication sharedApplication] endBackgroundTask:incallBgTask];
incallBgTask=0;
}
-
+
/*IOS specific*/
linphone_core_start_dtmf_stream(theLinphoneCore);
-
+
/*start the video preview in case we are in the main view*/
if ([LinphoneManager runningOnIpad] && linphone_core_video_enabled(theLinphoneCore) && [self lpConfigBoolForKey:@"preview_preference"]){
linphone_core_enable_video_preview(theLinphoneCore, TRUE);
@@ -1556,15 +1577,15 @@ static int comp_call_state_paused (const LinphoneCall* call, const void* param)
}
- (void)beginInterruption {
- LinphoneCall* c = linphone_core_get_current_call(theLinphoneCore);
- [LinphoneLogger logc:LinphoneLoggerLog format:"Sound interruption detected!"];
- if (c && linphone_call_get_state(c) == LinphoneCallStreamsRunning) {
- linphone_core_pause_call(theLinphoneCore, c);
- }
+ LinphoneCall* c = linphone_core_get_current_call(theLinphoneCore);
+ [LinphoneLogger logc:LinphoneLoggerLog format:"Sound interruption detected!"];
+ if (c && linphone_call_get_state(c) == LinphoneCallStreamsRunning) {
+ linphone_core_pause_call(theLinphoneCore, c);
+ }
}
- (void)endInterruption {
- [LinphoneLogger logc:LinphoneLoggerLog format:"Sound interruption ended!"];
+ [LinphoneLogger logc:LinphoneLoggerLog format:"Sound interruption ended!"];
}
- (void)refreshRegisters{
@@ -1577,205 +1598,205 @@ static int comp_call_state_paused (const LinphoneCall* call, const void* param)
- (void)copyDefaultSettings {
- NSString *src = [LinphoneManager bundleFile:[LinphoneManager runningOnIpad]?@"linphonerc~ipad":@"linphonerc"];
- NSString *dst = [LinphoneManager documentFile:@".linphonerc"];
- [LinphoneManager copyFile:src destination:dst override:FALSE];
+ NSString *src = [LinphoneManager bundleFile:[LinphoneManager runningOnIpad]?@"linphonerc~ipad":@"linphonerc"];
+ NSString *dst = [LinphoneManager documentFile:@".linphonerc"];
+ [LinphoneManager copyFile:src destination:dst override:FALSE];
}
#pragma mark - Audio route Functions
- (bool)allowSpeaker {
- bool notallow = false;
- CFStringRef lNewRoute = CFSTR("Unknown");
- UInt32 lNewRouteSize = sizeof(lNewRoute);
- OSStatus lStatus = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &lNewRouteSize, &lNewRoute);
- if (!lStatus && lNewRouteSize > 0) {
- NSString *route = (NSString *) lNewRoute;
- notallow = [route isEqualToString: @"Headset"] ||
- [route isEqualToString: @"Headphone"] ||
- [route isEqualToString: @"HeadphonesAndMicrophone"] ||
- [route isEqualToString: @"HeadsetInOut"] ||
- [route isEqualToString: @"Lineout"] ||
- [LinphoneManager runningOnIpad];
- CFRelease(lNewRoute);
- }
- return !notallow;
+ bool notallow = false;
+ CFStringRef lNewRoute = CFSTR("Unknown");
+ UInt32 lNewRouteSize = sizeof(lNewRoute);
+ OSStatus lStatus = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &lNewRouteSize, &lNewRoute);
+ if (!lStatus && lNewRouteSize > 0) {
+ NSString *route = (NSString *) lNewRoute;
+ notallow = [route isEqualToString: @"Headset"] ||
+ [route isEqualToString: @"Headphone"] ||
+ [route isEqualToString: @"HeadphonesAndMicrophone"] ||
+ [route isEqualToString: @"HeadsetInOut"] ||
+ [route isEqualToString: @"Lineout"] ||
+ [LinphoneManager runningOnIpad];
+ CFRelease(lNewRoute);
+ }
+ return !notallow;
}
static void audioRouteChangeListenerCallback (
- void *inUserData, // 1
- AudioSessionPropertyID inPropertyID, // 2
- UInt32 inPropertyValueSize, // 3
- const void *inPropertyValue // 4
- ) {
- if (inPropertyID != kAudioSessionProperty_AudioRouteChange) return; // 5
- LinphoneManager* lm = (LinphoneManager*)inUserData;
-
- bool speakerEnabled = false;
- CFStringRef lNewRoute = CFSTR("Unknown");
- UInt32 lNewRouteSize = sizeof(lNewRoute);
- OSStatus lStatus = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &lNewRouteSize, &lNewRoute);
- if (!lStatus && lNewRouteSize > 0) {
- NSString *route = (NSString *) lNewRoute;
- [LinphoneLogger logc:LinphoneLoggerLog format:"Current audio route is [%s]", [route cStringUsingEncoding:[NSString defaultCStringEncoding]]];
+ void *inUserData, // 1
+ AudioSessionPropertyID inPropertyID, // 2
+ UInt32 inPropertyValueSize, // 3
+ const void *inPropertyValue // 4
+ ) {
+ if (inPropertyID != kAudioSessionProperty_AudioRouteChange) return; // 5
+ LinphoneManager* lm = (LinphoneManager*)inUserData;
- speakerEnabled = [route isEqualToString: @"Speaker"] ||
- [route isEqualToString: @"SpeakerAndMicrophone"];
- if (![LinphoneManager runningOnIpad] && [route isEqualToString:@"HeadsetBT"] && !speakerEnabled) {
- lm.bluetoothEnabled = TRUE;
- lm.bluetoothAvailable = TRUE;
- NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
- [NSNumber numberWithBool:lm.bluetoothAvailable], @"available", nil];
- [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneBluetoothAvailabilityUpdate object:lm userInfo:dict];
- } else {
- lm.bluetoothEnabled = FALSE;
- }
- CFRelease(lNewRoute);
- }
-
- if(speakerEnabled != lm.speakerEnabled) { // Reforce value
- lm.speakerEnabled = lm.speakerEnabled;
- }
+ bool speakerEnabled = false;
+ CFStringRef lNewRoute = CFSTR("Unknown");
+ UInt32 lNewRouteSize = sizeof(lNewRoute);
+ OSStatus lStatus = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &lNewRouteSize, &lNewRoute);
+ if (!lStatus && lNewRouteSize > 0) {
+ NSString *route = (NSString *) lNewRoute;
+ [LinphoneLogger logc:LinphoneLoggerLog format:"Current audio route is [%s]", [route cStringUsingEncoding:[NSString defaultCStringEncoding]]];
+
+ speakerEnabled = [route isEqualToString: @"Speaker"] ||
+ [route isEqualToString: @"SpeakerAndMicrophone"];
+ if (![LinphoneManager runningOnIpad] && [route isEqualToString:@"HeadsetBT"] && !speakerEnabled) {
+ lm.bluetoothEnabled = TRUE;
+ lm.bluetoothAvailable = TRUE;
+ NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithBool:lm.bluetoothAvailable], @"available", nil];
+ [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneBluetoothAvailabilityUpdate object:lm userInfo:dict];
+ } else {
+ lm.bluetoothEnabled = FALSE;
+ }
+ CFRelease(lNewRoute);
+ }
+
+ if(speakerEnabled != lm.speakerEnabled) { // Reforce value
+ lm.speakerEnabled = lm.speakerEnabled;
+ }
}
- (void)setSpeakerEnabled:(BOOL)enable {
- speakerEnabled = enable;
+ speakerEnabled = enable;
- if(enable && [self allowSpeaker]) {
- UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
- AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute
- , sizeof (audioRouteOverride)
- , &audioRouteOverride);
- bluetoothEnabled = FALSE;
- } else {
- UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_None;
- AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute
- , sizeof (audioRouteOverride)
- , &audioRouteOverride);
- }
+ if(enable && [self allowSpeaker]) {
+ UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
+ AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute
+ , sizeof (audioRouteOverride)
+ , &audioRouteOverride);
+ bluetoothEnabled = FALSE;
+ } else {
+ UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_None;
+ AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute
+ , sizeof (audioRouteOverride)
+ , &audioRouteOverride);
+ }
- if (bluetoothAvailable) {
- UInt32 bluetoothInputOverride = bluetoothEnabled;
- AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryEnableBluetoothInput, sizeof(bluetoothInputOverride), &bluetoothInputOverride);
- }
+ if (bluetoothAvailable) {
+ UInt32 bluetoothInputOverride = bluetoothEnabled;
+ AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryEnableBluetoothInput, sizeof(bluetoothInputOverride), &bluetoothInputOverride);
+ }
}
- (void)setBluetoothEnabled:(BOOL)enable {
- if (bluetoothAvailable) {
- // The change of route will be done in setSpeakerEnabled
- bluetoothEnabled = enable;
- if (bluetoothEnabled) {
- [self setSpeakerEnabled:FALSE];
- } else {
- [self setSpeakerEnabled:speakerEnabled];
- }
- }
+ if (bluetoothAvailable) {
+ // The change of route will be done in setSpeakerEnabled
+ bluetoothEnabled = enable;
+ if (bluetoothEnabled) {
+ [self setSpeakerEnabled:FALSE];
+ } else {
+ [self setSpeakerEnabled:speakerEnabled];
+ }
+ }
}
#pragma mark - Call Functions
- (void)acceptCall:(LinphoneCall *)call {
- LinphoneCallParams* lcallParams = linphone_core_create_default_call_parameters(theLinphoneCore);
- if([self lpConfigBoolForKey:@"edge_opt_preference"]) {
- bool low_bandwidth = self.network == network_2g;
- if(low_bandwidth) {
- [LinphoneLogger log:LinphoneLoggerLog format:@"Low bandwidth mode"];
- }
- linphone_call_params_enable_low_bandwidth(lcallParams, low_bandwidth);
- }
+ LinphoneCallParams* lcallParams = linphone_core_create_default_call_parameters(theLinphoneCore);
+ if([self lpConfigBoolForKey:@"edge_opt_preference"]) {
+ bool low_bandwidth = self.network == network_2g;
+ if(low_bandwidth) {
+ [LinphoneLogger log:LinphoneLoggerLog format:@"Low bandwidth mode"];
+ }
+ linphone_call_params_enable_low_bandwidth(lcallParams, low_bandwidth);
+ }
- // workaround for video policy not correctly updated for automatic accept
- BOOL video = linphone_call_params_video_enabled(lcallParams);
- const LinphoneVideoPolicy* policy = linphone_core_get_video_policy(theLinphoneCore);
- video &= policy->automatically_accept;
- linphone_call_params_enable_video(lcallParams, video);
+ // workaround for video policy not correctly updated for automatic accept
+ BOOL video = linphone_call_params_video_enabled(lcallParams);
+ const LinphoneVideoPolicy* policy = linphone_core_get_video_policy(theLinphoneCore);
+ video &= policy->automatically_accept;
+ linphone_call_params_enable_video(lcallParams, video);
- linphone_core_accept_call_with_params(theLinphoneCore,call, lcallParams);
+ linphone_core_accept_call_with_params(theLinphoneCore,call, lcallParams);
}
- (void)call:(NSString *)address displayName:(NSString*)displayName transfer:(BOOL)transfer {
- if (!linphone_core_is_network_reachable(theLinphoneCore)) {
+ if (!linphone_core_is_network_reachable(theLinphoneCore)) {
UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Network Error",nil)
- message:NSLocalizedString(@"There is no network connection available, enable WIFI or WWAN prior to place a call",nil)
- delegate:nil
- cancelButtonTitle:NSLocalizedString(@"Continue",nil)
+ message:NSLocalizedString(@"There is no network connection available, enable WIFI or WWAN prior to place a call",nil)
+ delegate:nil
+ cancelButtonTitle:NSLocalizedString(@"Continue",nil)
otherButtonTitles:nil];
[error show];
- [error release];
+ [error release];
return;
}
-
- CTCallCenter* callCenter = [[CTCallCenter alloc] init];
- if ([callCenter currentCalls]!=nil) {
- [LinphoneLogger logc:LinphoneLoggerError format:"GSM call in progress, cancelling outgoing SIP call request"];
+
+ CTCallCenter* callCenter = [[CTCallCenter alloc] init];
+ if ([callCenter currentCalls]!=nil) {
+ [LinphoneLogger logc:LinphoneLoggerError format:"GSM call in progress, cancelling outgoing SIP call request"];
UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Cannot make call",nil)
- message:NSLocalizedString(@"Please terminate GSM call",nil)
- delegate:nil
- cancelButtonTitle:NSLocalizedString(@"Continue",nil)
+ message:NSLocalizedString(@"Please terminate GSM call",nil)
+ delegate:nil
+ cancelButtonTitle:NSLocalizedString(@"Continue",nil)
otherButtonTitles:nil];
[error show];
- [error release];
+ [error release];
[callCenter release];
return;
- }
- [callCenter release];
-
- LinphoneProxyConfig* proxyCfg;
+ }
+ [callCenter release];
+
+ LinphoneProxyConfig* proxyCfg;
//get default proxy
linphone_core_get_default_proxy(theLinphoneCore,&proxyCfg);
LinphoneCallParams* lcallParams = linphone_core_create_default_call_parameters(theLinphoneCore);
- if([self lpConfigBoolForKey:@"edge_opt_preference"]) {
- bool low_bandwidth = self.network == network_2g;
- if(low_bandwidth) {
- [LinphoneLogger log:LinphoneLoggerLog format:@"Low bandwidth mode"];
- }
- linphone_call_params_enable_low_bandwidth(lcallParams, low_bandwidth);
- }
+ if([self lpConfigBoolForKey:@"edge_opt_preference"]) {
+ bool low_bandwidth = self.network == network_2g;
+ if(low_bandwidth) {
+ [LinphoneLogger log:LinphoneLoggerLog format:@"Low bandwidth mode"];
+ }
+ linphone_call_params_enable_low_bandwidth(lcallParams, low_bandwidth);
+ }
LinphoneCall* call=NULL;
-
+
if ([address length] == 0) return; //just return
if ([address hasPrefix:@"sip:"] || [address hasPrefix:@"sips:"]) {
- LinphoneAddress* linphoneAddress = linphone_address_new([address cStringUsingEncoding:[NSString defaultCStringEncoding]]);
- if(displayName!=nil) {
- linphone_address_set_display_name(linphoneAddress,[displayName cStringUsingEncoding:[NSString defaultCStringEncoding]]);
- }
- if ([[LinphoneManager instance] lpConfigBoolForKey:@"override_domain_with_default_one"])
- linphone_address_set_domain(linphoneAddress, [[[LinphoneManager instance] lpConfigStringForKey:@"domain" forSection:@"wizard"] cStringUsingEncoding:[NSString defaultCStringEncoding]]);
- if(transfer) {
- linphone_core_transfer_call(theLinphoneCore, linphone_core_get_current_call(theLinphoneCore), [address cStringUsingEncoding:[NSString defaultCStringEncoding]]);
- } else {
- call=linphone_core_invite_address_with_params(theLinphoneCore, linphoneAddress, lcallParams);
- }
- linphone_address_destroy(linphoneAddress);
+ LinphoneAddress* linphoneAddress = linphone_address_new([address cStringUsingEncoding:[NSString defaultCStringEncoding]]);
+ if(displayName!=nil) {
+ linphone_address_set_display_name(linphoneAddress,[displayName cStringUsingEncoding:[NSString defaultCStringEncoding]]);
+ }
+ if ([[LinphoneManager instance] lpConfigBoolForKey:@"override_domain_with_default_one"])
+ linphone_address_set_domain(linphoneAddress, [[[LinphoneManager instance] lpConfigStringForKey:@"domain" forSection:@"wizard"] cStringUsingEncoding:[NSString defaultCStringEncoding]]);
+ if(transfer) {
+ linphone_core_transfer_call(theLinphoneCore, linphone_core_get_current_call(theLinphoneCore), [address cStringUsingEncoding:[NSString defaultCStringEncoding]]);
+ } else {
+ call=linphone_core_invite_address_with_params(theLinphoneCore, linphoneAddress, lcallParams);
+ }
+ linphone_address_destroy(linphoneAddress);
} else if (proxyCfg==nil){
UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Invalid SIP address",nil)
message:NSLocalizedString(@"Either configure a SIP proxy server from settings prior to place a call or use a valid SIP address (I.E sip:john@example.net)",nil)
- delegate:nil
- cancelButtonTitle:NSLocalizedString(@"Continue",nil)
+ delegate:nil
+ cancelButtonTitle:NSLocalizedString(@"Continue",nil)
otherButtonTitles:nil];
[error show];
[error release];
} else {
char normalizedUserName[256];
- LinphoneAddress* linphoneAddress = linphone_address_new(linphone_core_get_identity(theLinphoneCore));
+ LinphoneAddress* linphoneAddress = linphone_address_new(linphone_core_get_identity(theLinphoneCore));
linphone_proxy_config_normalize_number(proxyCfg,[address cStringUsingEncoding:[NSString defaultCStringEncoding]],normalizedUserName,sizeof(normalizedUserName));
- linphone_address_set_username(linphoneAddress, normalizedUserName);
- if(displayName!=nil) {
- linphone_address_set_display_name(linphoneAddress, [displayName cStringUsingEncoding:[NSString defaultCStringEncoding]]);
- }
- if ([[LinphoneManager instance] lpConfigBoolForKey:@"override_domain_with_default_one"])
- linphone_address_set_domain(linphoneAddress, [[[LinphoneManager instance] lpConfigStringForKey:@"domain" forSection:@"wizard"] cStringUsingEncoding:[NSString defaultCStringEncoding]]);
- if(transfer) {
- linphone_core_transfer_call(theLinphoneCore, linphone_core_get_current_call(theLinphoneCore), linphone_address_as_string_uri_only(linphoneAddress));
- } else {
- call=linphone_core_invite_address_with_params(theLinphoneCore, linphoneAddress, lcallParams);
- }
- linphone_address_destroy(linphoneAddress);
+ linphone_address_set_username(linphoneAddress, normalizedUserName);
+ if(displayName!=nil) {
+ linphone_address_set_display_name(linphoneAddress, [displayName cStringUsingEncoding:[NSString defaultCStringEncoding]]);
+ }
+ if ([[LinphoneManager instance] lpConfigBoolForKey:@"override_domain_with_default_one"])
+ linphone_address_set_domain(linphoneAddress, [[[LinphoneManager instance] lpConfigStringForKey:@"domain" forSection:@"wizard"] cStringUsingEncoding:[NSString defaultCStringEncoding]]);
+ if(transfer) {
+ linphone_core_transfer_call(theLinphoneCore, linphone_core_get_current_call(theLinphoneCore), linphone_address_as_string_uri_only(linphoneAddress));
+ } else {
+ call=linphone_core_invite_address_with_params(theLinphoneCore, linphoneAddress, lcallParams);
+ }
+ linphone_address_destroy(linphoneAddress);
}
if (call) {
LinphoneCallAppData* data = [[LinphoneCallAppData alloc] init];
- data->videoRequested = linphone_call_params_video_enabled(lcallParams); /* will be used later to notify user if video was not activated because of the linphone core*/
+ data->videoRequested = linphone_call_params_video_enabled(lcallParams); /* will be used later to notify user if video was not activated because of the linphone core*/
linphone_call_set_user_pointer(call, data);
}
linphone_call_params_destroy(lcallParams);
@@ -1785,26 +1806,26 @@ static void audioRouteChangeListenerCallback (
#pragma mark - Property Functions
- (void)setPushNotificationToken:(NSData *)apushNotificationToken {
- if(apushNotificationToken == pushNotificationToken) {
- return;
- }
- if(pushNotificationToken != nil) {
- [pushNotificationToken release];
- pushNotificationToken = nil;
- }
-
- if(apushNotificationToken != nil) {
- pushNotificationToken = [apushNotificationToken retain];
- }
- if([LinphoneManager isLcReady]) {
+ if(apushNotificationToken == pushNotificationToken) {
+ return;
+ }
+ if(pushNotificationToken != nil) {
+ [pushNotificationToken release];
+ pushNotificationToken = nil;
+ }
+
+ if(apushNotificationToken != nil) {
+ pushNotificationToken = [apushNotificationToken retain];
+ }
+ if([LinphoneManager isLcReady]) {
LinphoneProxyConfig *cfg=nil;
linphone_core_get_default_proxy(theLinphoneCore, &cfg);
- if (cfg) {
+ if (cfg) {
linphone_proxy_config_edit(cfg);
[self addPushTokenToProxyConfig: cfg];
linphone_proxy_config_done(cfg);
}
- }
+ }
}
- (void)addPushTokenToProxyConfig:(LinphoneProxyConfig*)proxyCfg{
@@ -1822,70 +1843,65 @@ static void audioRouteChangeListenerCallback (
#else
#define APPMODE_SUFFIX @"prod"
#endif
- NSString *params;
- if( [[[UIDevice currentDevice] systemVersion] doubleValue] >= 7 ){ /// use silent push for ios7 devices
- params = [NSString stringWithFormat:@"app-id=%@.%@;pn-type=apple;pn-tok=%@;pn-msg-str=IC_SIL;pn-call-str=IC_SIL;pn-call-snd=empty;pn-msg-snd=msg.caf", [[NSBundle mainBundle] bundleIdentifier],APPMODE_SUFFIX,tokenString];
- } else {
- params = [NSString stringWithFormat:@"app-id=%@.%@;pn-type=apple;pn-tok=%@;pn-msg-str=IM_MSG;pn-call-str=IC_MSG;pn-call-snd=ring.caf;pn-msg-snd=msg.caf", [[NSBundle mainBundle] bundleIdentifier],APPMODE_SUFFIX,tokenString];
- }
+ NSString *params = [NSString stringWithFormat:@"app-id=%@.%@;pn-type=apple;pn-tok=%@;pn-msg-str=IM_MSG;pn-call-str=IC_MSG;pn-call-snd=ring.caf;pn-msg-snd=msg.caf", [[NSBundle mainBundle] bundleIdentifier],APPMODE_SUFFIX,tokenString];
- linphone_proxy_config_set_contact_uri_parameters(proxyCfg, [params UTF8String]);
+ linphone_proxy_config_set_contact_uri_parameters(proxyCfg, [params UTF8String]);
linphone_proxy_config_set_contact_parameters(proxyCfg, NULL);
- }
+ }
}
#pragma mark - Misc Functions
+ (NSString*)bundleFile:(NSString*)file {
- return [[NSBundle mainBundle] pathForResource:[file stringByDeletingPathExtension] ofType:[file pathExtension]];
+ return [[NSBundle mainBundle] pathForResource:[file stringByDeletingPathExtension] ofType:[file pathExtension]];
}
+ (NSString*)documentFile:(NSString*)file {
- NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
- NSString *documentsPath = [paths objectAtIndex:0];
- return [documentsPath stringByAppendingPathComponent:file];
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+ NSString *documentsPath = [paths objectAtIndex:0];
+ return [documentsPath stringByAppendingPathComponent:file];
}
+ (int)unreadMessageCount {
- int count = 0;
- MSList* rooms = linphone_core_get_chat_rooms([LinphoneManager getLc]);
- MSList* item = rooms;
- while (item) {
- LinphoneChatRoom* room = (LinphoneChatRoom*)item->data;
- if( room ){
- count += linphone_chat_room_get_unread_messages_count(room);
- }
- item = item->next;
- }
- return count;
+ int count = 0;
+ MSList* rooms = linphone_core_get_chat_rooms([LinphoneManager getLc]);
+ MSList* item = rooms;
+ while (item) {
+ LinphoneChatRoom* room = (LinphoneChatRoom*)item->data;
+ if( room ){
+ count += linphone_chat_room_get_unread_messages_count(room);
+ }
+ item = item->next;
+ }
+ return count;
}
+ (BOOL)copyFile:(NSString*)src destination:(NSString*)dst override:(BOOL)override {
- NSFileManager *fileManager = [NSFileManager defaultManager];
- NSError *error = nil;
- if ([fileManager fileExistsAtPath:dst] == YES) {
- if(override) {
- [fileManager removeItemAtPath:dst error:&error];
- if(error != nil) {
- [LinphoneLogger log:LinphoneLoggerError format:@"Can't remove \"%@\": %@", dst, [error localizedDescription]];
- return FALSE;
- }
- } else {
- [LinphoneLogger log:LinphoneLoggerWarning format:@"\"%@\" already exists", dst];
- return FALSE;
- }
- }
- if ([fileManager fileExistsAtPath:src] == NO) {
- [LinphoneLogger log:LinphoneLoggerError format:@"Can't find \"%@\": %@", src, [error localizedDescription]];
- return FALSE;
- }
- [fileManager copyItemAtPath:src toPath:dst error:&error];
- if(error != nil) {
- [LinphoneLogger log:LinphoneLoggerError format:@"Can't copy \"%@\" to \"%@\": %@", src, dst, [error localizedDescription]];
- return FALSE;
- }
- return TRUE;
+ NSFileManager *fileManager = [NSFileManager defaultManager];
+ NSError *error = nil;
+ if ([fileManager fileExistsAtPath:dst] == YES) {
+ if(override) {
+ [fileManager removeItemAtPath:dst error:&error];
+ if(error != nil) {
+ [LinphoneLogger log:LinphoneLoggerError format:@"Can't remove \"%@\": %@", dst, [error localizedDescription]];
+ return FALSE;
+ }
+ } else {
+ [LinphoneLogger log:LinphoneLoggerWarning format:@"\"%@\" already exists", dst];
+ return FALSE;
+ }
+ }
+ if ([fileManager fileExistsAtPath:src] == NO) {
+ [LinphoneLogger log:LinphoneLoggerError format:@"Can't find \"%@\": %@", src, [error localizedDescription]];
+ return FALSE;
+ }
+ [fileManager copyItemAtPath:src toPath:dst error:&error];
+ if(error != nil) {
+ [LinphoneLogger log:LinphoneLoggerError format:@"Can't copy \"%@\" to \"%@\": %@", src, dst, [error localizedDescription]];
+ return FALSE;
+ }
+ return TRUE;
}
- (void)configureVbrCodecs{
@@ -1907,36 +1923,36 @@ static void audioRouteChangeListenerCallback (
+(id)getMessageAppDataForKey:(NSString*)key inMessage:(LinphoneChatMessage*)msg {
- if(msg == nil ) return nil;
+ if(msg == nil ) return nil;
- id value = nil;
- const char* appData = linphone_chat_message_get_appdata(msg);
- if( appData) {
- NSDictionary* appDataDict = [NSJSONSerialization JSONObjectWithData:[NSData dataWithBytes:appData length:strlen(appData)] options:0 error:nil];
- value = [appDataDict objectForKey:key];
- }
- return value;
+ id value = nil;
+ const char* appData = linphone_chat_message_get_appdata(msg);
+ if( appData) {
+ NSDictionary* appDataDict = [NSJSONSerialization JSONObjectWithData:[NSData dataWithBytes:appData length:strlen(appData)] options:0 error:nil];
+ value = [appDataDict objectForKey:key];
+ }
+ return value;
}
+(void)setValueInMessageAppData:(id)value forKey:(NSString*)key inMessage:(LinphoneChatMessage*)msg {
- NSMutableDictionary* appDataDict = [NSMutableDictionary dictionary];
- const char* appData = linphone_chat_message_get_appdata(msg);
- if( appData) {
- appDataDict = [NSJSONSerialization JSONObjectWithData:[NSData dataWithBytes:appData length:strlen(appData)] options:NSJSONReadingMutableContainers error:nil];
- }
+ NSMutableDictionary* appDataDict = [NSMutableDictionary dictionary];
+ const char* appData = linphone_chat_message_get_appdata(msg);
+ if( appData) {
+ appDataDict = [NSJSONSerialization JSONObjectWithData:[NSData dataWithBytes:appData length:strlen(appData)] options:NSJSONReadingMutableContainers error:nil];
+ }
- [appDataDict setValue:value forKey:key];
+ [appDataDict setValue:value forKey:key];
- NSData* data = [NSJSONSerialization dataWithJSONObject:appDataDict options:0 error:nil];
- NSString* appdataJSON = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
- linphone_chat_message_set_appdata(msg, [appdataJSON UTF8String] );
+ NSData* data = [NSJSONSerialization dataWithJSONObject:appDataDict options:0 error:nil];
+ NSString* appdataJSON = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
+ linphone_chat_message_set_appdata(msg, [appdataJSON UTF8String] );
}
#pragma mark - LPConfig Functions
- (void)lpConfigSetString:(NSString*)value forKey:(NSString*)key {
- [self lpConfigSetString:value forKey:key forSection:[NSString stringWithUTF8String:LINPHONERC_APPLICATION_KEY]];
+ [self lpConfigSetString:value forKey:key forSection:[NSString stringWithUTF8String:LINPHONERC_APPLICATION_KEY]];
}
- (void)lpConfigSetString:(NSString*)value forKey:(NSString*)key forSection:(NSString *)section {
@@ -1945,7 +1961,7 @@ static void audioRouteChangeListenerCallback (
}
- (NSString*)lpConfigStringForKey:(NSString*)key {
- return [self lpConfigStringForKey:key forSection:[NSString stringWithUTF8String:LINPHONERC_APPLICATION_KEY]];
+ return [self lpConfigStringForKey:key forSection:[NSString stringWithUTF8String:LINPHONERC_APPLICATION_KEY]];
}
- (NSString*)lpConfigStringForKey:(NSString*)key withDefault:(NSString*)defaultValue {
NSString* value = [self lpConfigStringForKey:key];
@@ -1953,7 +1969,7 @@ static void audioRouteChangeListenerCallback (
}
- (NSString*)lpConfigStringForKey:(NSString*)key forSection:(NSString *)section {
- if (!key) return nil;
+ if (!key) return nil;
const char* value = lp_config_get_string(configDb, [section UTF8String], [key UTF8String], NULL);
if (value)
return [NSString stringWithUTF8String:value];
@@ -1962,25 +1978,25 @@ static void audioRouteChangeListenerCallback (
}
- (void)lpConfigSetInt:(NSInteger)value forKey:(NSString*)key {
- [self lpConfigSetInt:value forKey:key forSection:[NSString stringWithUTF8String:LINPHONERC_APPLICATION_KEY]];
+ [self lpConfigSetInt:value forKey:key forSection:[NSString stringWithUTF8String:LINPHONERC_APPLICATION_KEY]];
}
- (void)lpConfigSetInt:(NSInteger)value forKey:(NSString*)key forSection:(NSString *)section {
- if (!key) return;
+ if (!key) return;
lp_config_set_int(configDb, [section UTF8String], [key UTF8String], value );
}
- (NSInteger)lpConfigIntForKey:(NSString*)key {
- return [self lpConfigIntForKey:key forSection:[NSString stringWithUTF8String:LINPHONERC_APPLICATION_KEY]];
+ return [self lpConfigIntForKey:key forSection:[NSString stringWithUTF8String:LINPHONERC_APPLICATION_KEY]];
}
- (NSInteger)lpConfigIntForKey:(NSString*)key forSection:(NSString *)section {
- if (!key) return -1;
+ if (!key) return -1;
return lp_config_get_int(configDb, [section UTF8String], [key UTF8String], -1);
}
- (void)lpConfigSetBool:(BOOL)value forKey:(NSString*)key {
- [self lpConfigSetBool:value forKey:key forSection:[NSString stringWithUTF8String:LINPHONERC_APPLICATION_KEY]];
+ [self lpConfigSetBool:value forKey:key forSection:[NSString stringWithUTF8String:LINPHONERC_APPLICATION_KEY]];
}
- (void)lpConfigSetBool:(BOOL)value forKey:(NSString*)key forSection:(NSString *)section {
@@ -1988,7 +2004,7 @@ static void audioRouteChangeListenerCallback (
}
- (BOOL)lpConfigBoolForKey:(NSString*)key {
- return [self lpConfigBoolForKey:key forSection:[NSString stringWithUTF8String:LINPHONERC_APPLICATION_KEY]];
+ return [self lpConfigBoolForKey:key forSection:[NSString stringWithUTF8String:LINPHONERC_APPLICATION_KEY]];
}
- (BOOL)lpConfigBoolForKey:(NSString*)key forSection:(NSString *)section {
@@ -1996,11 +2012,11 @@ static void audioRouteChangeListenerCallback (
}
- (void)silentPushFailed:(NSTimer*)timer
{
- if( silentPushCompletion ){
- [LinphoneLogger log:LinphoneLoggerLog format:@"silentPush failed, silentPushCompletion block: %p", silentPushCompletion ];
- silentPushCompletion(UIBackgroundFetchResultNoData);
- silentPushCompletion = nil;
- }
+ if( silentPushCompletion ){
+ [LinphoneLogger log:LinphoneLoggerLog format:@"silentPush failed, silentPushCompletion block: %p", silentPushCompletion ];
+ silentPushCompletion(UIBackgroundFetchResultNoData);
+ silentPushCompletion = nil;
+ }
}
@@ -2016,21 +2032,21 @@ static void audioRouteChangeListenerCallback (
}
- (void)setupGSMInteraction {
-
+
[self removeCTCallCenterCb];
- mCallCenter = [[CTCallCenter alloc] init];
+ mCallCenter = [[CTCallCenter alloc] init];
[LinphoneLogger log:LinphoneLoggerLog format:@"Adding CT call center listener [%p]",mCallCenter];
- mCallCenter.callEventHandler = ^(CTCall* call) {
+ mCallCenter.callEventHandler = ^(CTCall* call) {
// post on main thread
[self performSelectorOnMainThread:@selector(handleGSMCallInteration:)
withObject:mCallCenter
waitUntilDone:YES];
};
-
+
}
- (void)handleGSMCallInteration: (id) cCenter {
- CTCallCenter* ct = (CTCallCenter*) cCenter;
+ CTCallCenter* ct = (CTCallCenter*) cCenter;
/* pause current call, if any */
LinphoneCall* call = linphone_core_get_current_call(theLinphoneCore);
if ([ct currentCalls]!=nil) {
@@ -2062,27 +2078,27 @@ static void audioRouteChangeListenerCallback (
#pragma Tunnel
- (void)setTunnelMode:(TunnelMode)atunnelMode {
- LinphoneTunnel *tunnel = linphone_core_get_tunnel(theLinphoneCore);
- tunnelMode = atunnelMode;
- switch (tunnelMode) {
- case tunnel_off:
- linphone_tunnel_enable(tunnel, false);
- break;
- case tunnel_on:
- linphone_tunnel_enable(tunnel, true);
- break;
- case tunnel_wwan:
- if (connectivity != wwan) {
- linphone_tunnel_enable(tunnel, false);
- } else {
- linphone_tunnel_enable(tunnel, true);
- }
- break;
- case tunnel_auto:
- linphone_tunnel_auto_detect(tunnel);
- break;
-
- }
+ LinphoneTunnel *tunnel = linphone_core_get_tunnel(theLinphoneCore);
+ tunnelMode = atunnelMode;
+ switch (tunnelMode) {
+ case tunnel_off:
+ linphone_tunnel_enable(tunnel, false);
+ break;
+ case tunnel_on:
+ linphone_tunnel_enable(tunnel, true);
+ break;
+ case tunnel_wwan:
+ if (connectivity != wwan) {
+ linphone_tunnel_enable(tunnel, false);
+ } else {
+ linphone_tunnel_enable(tunnel, true);
+ }
+ break;
+ case tunnel_auto:
+ linphone_tunnel_auto_detect(tunnel);
+ break;
+
+ }
}
diff --git a/Classes/LinphoneUI/Base.lproj/UICallBar.xib b/Classes/LinphoneUI/Base.lproj/UICallBar.xib
index b77602129..2144dad66 100644
--- a/Classes/LinphoneUI/Base.lproj/UICallBar.xib
+++ b/Classes/LinphoneUI/Base.lproj/UICallBar.xib
@@ -1,8 +1,8 @@
-
+
-
+
@@ -160,7 +160,7 @@
-
+
@@ -481,6 +481,8 @@
+
+
@@ -590,7 +592,7 @@
-
+
@@ -897,7 +899,9 @@
+
+
@@ -1026,4 +1030,9 @@
+
+
+
+
+
diff --git a/Classes/LinphoneUI/Base.lproj/UICallBar~ipad.xib b/Classes/LinphoneUI/Base.lproj/UICallBar~ipad.xib
index 3431e4667..62f76c9a1 100644
--- a/Classes/LinphoneUI/Base.lproj/UICallBar~ipad.xib
+++ b/Classes/LinphoneUI/Base.lproj/UICallBar~ipad.xib
@@ -1,8 +1,8 @@
-
+
-
+
@@ -145,7 +145,7 @@
-
+
@@ -352,7 +352,9 @@
+
+
@@ -472,7 +474,7 @@
-
+
@@ -696,6 +698,8 @@
+
+
@@ -787,4 +791,9 @@
+
+
+
+
+
diff --git a/Classes/LinphoneUI/UICompositeViewController.h b/Classes/LinphoneUI/UICompositeViewController.h
index faef77352..3af7e6741 100644
--- a/Classes/LinphoneUI/UICompositeViewController.h
+++ b/Classes/LinphoneUI/UICompositeViewController.h
@@ -35,6 +35,7 @@
@property (assign) BOOL fullscreen;
@property (assign) BOOL landscapeMode;
@property (assign) BOOL portraitMode;
+@property (assign) BOOL darkBackground;
- (id)copy;
- (BOOL)equal:(UICompositeViewDescription*) description;
@@ -71,6 +72,7 @@
- (void)setFullScreen:(BOOL) enabled;
- (void)setStateBarHidden:(BOOL) hidden;
- (void)setToolBarHidden:(BOOL) hidden;
+- (BOOL)currentViewSupportsLandscape;
- (UIViewController *)getCachedController:(NSString*)name;
- (UIViewController *)getCurrentViewController;
- (UIInterfaceOrientation)currentOrientation;
diff --git a/Classes/LinphoneUI/UICompositeViewController.m b/Classes/LinphoneUI/UICompositeViewController.m
index 97e29d9aa..ac679a3a2 100644
--- a/Classes/LinphoneUI/UICompositeViewController.m
+++ b/Classes/LinphoneUI/UICompositeViewController.m
@@ -33,6 +33,7 @@
@synthesize landscapeMode;
@synthesize portraitMode;
+
- (id)copy {
UICompositeViewDescription *copy = [UICompositeViewDescription alloc];
copy.content = self.content;
@@ -43,6 +44,7 @@
copy.fullscreen = self.fullscreen;
copy.landscapeMode = self.landscapeMode;
copy.portraitMode = self.portraitMode;
+ copy.darkBackground = self.darkBackground;
return copy;
}
@@ -56,7 +58,7 @@
tabBarEnabled:(BOOL) atabBarEnabled
fullscreen:(BOOL) afullscreen
landscapeMode:(BOOL) alandscapeMode
- portraitMode:(BOOL) aportraitMode {
+ portraitMode:(BOOL) aportraitMode{
self.name = aname;
self.content = acontent;
self.stateBar = astateBar;
@@ -66,6 +68,7 @@
self.fullscreen = afullscreen;
self.landscapeMode = alandscapeMode;
self.portraitMode = aportraitMode;
+ self.darkBackground = false;
return self;
}
@@ -165,13 +168,31 @@
#pragma mark - ViewController Functions
+- (void)updateViewsFramesAccordingToLaunchOrientation {
+ CGRect frame = [self.view frame]; // this view has the correct size at launch (1024/768 for iPad, 320*{568,480} for iPhone)
+ UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
+ BOOL portrait = UIInterfaceOrientationIsPortrait(orientation);
+ CGRect oppositeFrame = frame;
+ oppositeFrame.size.height = frame.size.width;
+ oppositeFrame.size.width = frame.size.height;
+
+ // if we start in portrait, the landscape view must get the opposite height and width
+ if( portrait || [[UIDevice currentDevice].systemName floatValue] < 8 ){
+ Linphone_log(@"landscape get opposite: %@", NSStringFromCGSize(oppositeFrame.size));
+ [landscapeView setFrame:oppositeFrame];
+ } else {
+ // if we start in landscape, the landscape view has to get the current size,
+ // whereas the portrait has to get the opposite
+ Linphone_log(@"landscape get frame: %@ and portrait gets opposite: %@", NSStringFromCGSize(frame.size), NSStringFromCGSize(oppositeFrame.size));
+ [landscapeView setFrame:frame];
+ [portraitView setFrame:oppositeFrame];
+ }
+}
+
- (void)viewDidLoad {
- /* Force landscape view to match portrait view */
- CGRect frame = [portraitView frame];
- int height = frame.size.width;
- frame.size.width = frame.size.height;
- frame.size.height = height;
- [landscapeView setFrame:frame];
+ /* Force landscape view to match portrait view, because portrait view inherits
+ the device screen size at load */
+ [self updateViewsFramesAccordingToLaunchOrientation];
[super viewDidLoad];
}
@@ -215,6 +236,8 @@
[self.stateBarViewController viewDidDisappear:animated];
}
+#pragma mark - Rotation messages
+
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
currentOrientation = toInterfaceOrientation;
[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
@@ -224,7 +247,7 @@
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
- [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
+ [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; // Will invoke TPMultiLayout
[self.contentViewController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
[self.tabBarViewController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
[self.stateBarViewController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
@@ -265,57 +288,26 @@
*/
+ (void)setOrientation:(UIInterfaceOrientation)orientation animated:(BOOL)animated {
UIView *firstResponder = nil;
- for(UIWindow *window in [[UIApplication sharedApplication] windows]) {
- if([NSStringFromClass(window.class) isEqualToString:@"UITextEffectsWindow"] ||
- [NSStringFromClass(window.class) isEqualToString:@"_UIAlertOverlayWindow"] ) {
- continue;
- }
- UIView *view = window;
- UIViewController *controller = nil;
- CGRect frame = [view frame];
- if([window isKindOfClass:[UILinphoneWindow class]]) {
- controller = window.rootViewController;
- view = controller.view;
- }
- UIInterfaceOrientation oldOrientation = controller.interfaceOrientation;
-
- NSTimeInterval animationDuration = 0.0;
- if(animated) {
- animationDuration = 0.3f;
- }
- [controller willRotateToInterfaceOrientation:orientation duration:animationDuration];
- if(animated) {
- [UIView beginAnimations:nil context:nil];
- [UIView setAnimationDuration:animationDuration];
- }
- switch (orientation) {
- case UIInterfaceOrientationPortrait:
- [view setTransform: CGAffineTransformMakeRotation(0)];
- break;
- case UIInterfaceOrientationPortraitUpsideDown:
- [view setTransform: CGAffineTransformMakeRotation(M_PI)];
- break;
- case UIInterfaceOrientationLandscapeLeft:
- [view setTransform: CGAffineTransformMakeRotation(-M_PI / 2)];
- break;
- case UIInterfaceOrientationLandscapeRight:
- [view setTransform: CGAffineTransformMakeRotation(M_PI / 2)];
- break;
- default:
- break;
- }
- if([window isKindOfClass:[UILinphoneWindow class]]) {
- [view setFrame:frame];
- }
- [controller willAnimateRotationToInterfaceOrientation:orientation duration:animationDuration];
- if(animated) {
- [UIView commitAnimations];
- }
- [controller didRotateFromInterfaceOrientation:oldOrientation];
- if(firstResponder == nil) {
- firstResponder = [UICompositeViewController findFirstResponder:view];
- }
+
+ UIViewController *controller = nil;
+
+ controller = [[UIApplication sharedApplication] keyWindow].rootViewController;
+ CGRect frame = [[UIScreen mainScreen] bounds];
+ UIInterfaceOrientation oldOrientation = controller.interfaceOrientation;
+
+ NSTimeInterval animationDuration = animated? 0.3f : 0.0;
+
+ [controller willRotateToInterfaceOrientation:orientation duration:animationDuration];
+ [controller willAnimateRotationToInterfaceOrientation:orientation duration:animationDuration];
+ [controller didRotateFromInterfaceOrientation:oldOrientation];
+ [UIView animateWithDuration:animationDuration animations:^{
+ [controller.view setFrame:frame];
+ }];
+
+ if(firstResponder == nil) {
+ firstResponder = [UICompositeViewController findFirstResponder:controller.view];
}
+
[[UIApplication sharedApplication] setStatusBarOrientation:orientation animated:animated];
if(firstResponder) {
[firstResponder resignFirstResponder];
@@ -351,11 +343,6 @@
}
if(remove) {
[LinphoneLogger log:LinphoneLoggerLog format:@"Free cached view: %@", key];
- UIViewController *vc = [viewControllerCache objectForKey:key];
- if ([[UIDevice currentDevice].systemVersion doubleValue] >= 5.0) {
- [vc viewWillUnload];
- }
- [vc viewDidUnload];
[viewControllerCache removeObjectForKey:key];
}
}
@@ -499,8 +486,8 @@
UIViewController *newContentViewController = [self getCachedController:description.content];
UIViewController *newStateBarViewController = [self getCachedController:description.stateBar];
- UIViewController *newTabBarViewController = [self getCachedController:description.tabBar];
-
+ UIViewController *newTabBarViewController = [self getCachedController:description.tabBar];
+
[UICompositeViewController removeSubView: oldContentViewController];
if(oldTabBarViewController != nil && oldTabBarViewController != newTabBarViewController) {
[UICompositeViewController removeSubView:oldTabBarViewController];
@@ -508,15 +495,20 @@
if(oldStateBarViewController != nil && oldStateBarViewController != newStateBarViewController) {
[UICompositeViewController removeSubView:oldStateBarViewController];
}
-
+
self.stateBarViewController = newStateBarViewController;
self.contentViewController = newContentViewController;
self.tabBarViewController = newTabBarViewController;
// Update rotation
- UIInterfaceOrientation correctOrientation = [self getCorrectInterfaceOrientation:[[UIDevice currentDevice] orientation]];
+ UIInterfaceOrientation correctOrientation = [self getCorrectInterfaceOrientation:(UIDeviceOrientation)[UIApplication sharedApplication].statusBarOrientation];
if(currentOrientation != correctOrientation) {
[UICompositeViewController setOrientation:correctOrientation animated:currentOrientation!=UIDeviceOrientationUnknown];
+ if( UIInterfaceOrientationIsLandscape(correctOrientation) ){
+ [self.contentViewController willAnimateRotationToInterfaceOrientation:correctOrientation duration:0];
+ [self.tabBarViewController willAnimateRotationToInterfaceOrientation:correctOrientation duration:0];
+ [self.stateBarViewController willAnimateRotationToInterfaceOrientation:correctOrientation duration:0];
+ }
} else {
if(oldContentViewController != newContentViewController) {
UIInterfaceOrientation oldOrientation = self.contentViewController.interfaceOrientation;
@@ -536,7 +528,7 @@
[self.stateBarViewController willAnimateRotationToInterfaceOrientation:correctOrientation duration:0];
[self.stateBarViewController didRotateFromInterfaceOrientation:oldOrientation];
}
- }
+ }
} else {
oldViewDescription = (currentViewDescription != nil)? [currentViewDescription copy]: nil;
}
@@ -681,4 +673,8 @@
return [[self.contentViewController retain] autorelease];
}
+- (BOOL)currentViewSupportsLandscape {
+ return currentViewDescription ? currentViewDescription.landscapeMode : FALSE;
+}
+
@end
diff --git a/Classes/LinphoneUI/UIDigitButton.h b/Classes/LinphoneUI/UIDigitButton.h
index 4b7d9f0e4..b680bab2c 100644
--- a/Classes/LinphoneUI/UIDigitButton.h
+++ b/Classes/LinphoneUI/UIDigitButton.h
@@ -22,7 +22,7 @@
#import "UILongTouchButton.h"
-@interface UIDigitButton : UILongTouchButton {
+@interface UIDigitButton : UILongTouchButton {
}
@property (nonatomic, retain) IBOutlet UITextField* addressField;
diff --git a/Classes/LinphoneUI/UIDigitButton.m b/Classes/LinphoneUI/UIDigitButton.m
index f6d0cdb4c..4f1fc1683 100644
--- a/Classes/LinphoneUI/UIDigitButton.m
+++ b/Classes/LinphoneUI/UIDigitButton.m
@@ -91,17 +91,4 @@
linphone_core_stop_dtmf([LinphoneManager getLc]);
}
-
-#pragma mark - UILongTouchButtonDelegate Functions
-
-- (void)onRepeatTouch {
-}
-
-- (void)onLongTouch {
- if (digit == '0') {
- NSString* newAddress = [[addressField.text substringToIndex: [addressField.text length]-1] stringByAppendingString:@"+"];
- [addressField setText:newAddress];
- }
-}
-
@end
diff --git a/Classes/LinphoneUI/UIDigitButtonLongPlus.h b/Classes/LinphoneUI/UIDigitButtonLongPlus.h
new file mode 100644
index 000000000..f1cf5b3c9
--- /dev/null
+++ b/Classes/LinphoneUI/UIDigitButtonLongPlus.h
@@ -0,0 +1,29 @@
+
+/* UIDigitButton.h
+ *
+ * Copyright (C) 2011 Belledonne Comunications, Grenoble, France
+ *
+ * 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.
+ */
+
+#import
+
+#import "UIDigitButton.h"
+
+
+@interface UIDigitButtonLongPlus : UIDigitButton {
+}
+
+@end
diff --git a/Classes/LinphoneUI/UIDigitButtonLongPlus.m b/Classes/LinphoneUI/UIDigitButtonLongPlus.m
new file mode 100644
index 000000000..2b2ffbbf6
--- /dev/null
+++ b/Classes/LinphoneUI/UIDigitButtonLongPlus.m
@@ -0,0 +1,34 @@
+/* UIDigitButton.m
+ *
+ * Copyright (C) 2011 Belledonne Comunications, Grenoble, France
+ *
+ * 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.
+ */
+
+#import "UIDigitButtonLongPlus.h"
+
+@implementation UIDigitButtonLongPlus
+
+#pragma mark - UILongTouchButtonDelegate Functions
+
+- (void)onRepeatTouch {
+}
+
+- (void)onLongTouch {
+ NSString* newAddress = [[self.addressField.text substringToIndex: [self.addressField.text length]-1] stringByAppendingString:@"+"];
+ [self.addressField setText:newAddress];
+}
+
+@end
diff --git a/Classes/LinphoneUI/UIDigitButtonLongVoiceMail.h b/Classes/LinphoneUI/UIDigitButtonLongVoiceMail.h
new file mode 100644
index 000000000..8117a66a7
--- /dev/null
+++ b/Classes/LinphoneUI/UIDigitButtonLongVoiceMail.h
@@ -0,0 +1,29 @@
+
+/* UIDigitButton.h
+ *
+ * Copyright (C) 2011 Belledonne Comunications, Grenoble, France
+ *
+ * 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.
+ */
+
+#import
+
+#import "UIDigitButton.h"
+
+
+@interface UIDigitButtonLongVoiceMail : UIDigitButton {
+}
+
+@end
diff --git a/Classes/LinphoneUI/UIDigitButtonLongVoiceMail.m b/Classes/LinphoneUI/UIDigitButtonLongVoiceMail.m
new file mode 100644
index 000000000..ba412557e
--- /dev/null
+++ b/Classes/LinphoneUI/UIDigitButtonLongVoiceMail.m
@@ -0,0 +1,45 @@
+/* UIDigitButton.m
+ *
+ * Copyright (C) 2011 Belledonne Comunications, Grenoble, France
+ *
+ * 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.
+ */
+
+#import "UIDigitButtonLongVoiceMail.h"
+#import "Utils.h"
+#include "LinphoneManager.h"
+
+@implementation UIDigitButtonLongVoiceMail
+
+#pragma mark - UILongTouchButtonDelegate Functions
+
+- (void)onRepeatTouch {
+}
+
+- (void)onLongTouch {
+ if(![LinphoneManager isLcReady]) {
+ [LinphoneLogger log:LinphoneLoggerWarning format:@"Cannot call voice mail: Linphone core not ready"];
+ return;
+ }
+ LinphoneManager* lm = [LinphoneManager instance];
+
+ NSString * voiceMailUri = [lm lpConfigStringForKey:@"voice_mail_uri" withDefault:NULL];
+
+ if (voiceMailUri != NULL) {
+ [lm call:voiceMailUri displayName:NSLocalizedString(@"Voice mail",nil) transfer:FALSE];
+ }
+}
+
+@end
diff --git a/Classes/LinphoneUI/UIMainBar.m b/Classes/LinphoneUI/UIMainBar.m
index 899435fab..dbacbeb29 100644
--- a/Classes/LinphoneUI/UIMainBar.m
+++ b/Classes/LinphoneUI/UIMainBar.m
@@ -4,16 +4,16 @@
*
* 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 Library 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
+ * 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 Library 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.
*/
@@ -46,7 +46,7 @@ static NSString * const kDisappearAnimation = @"disappear";
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
-
+
[historyButton release];
[contactsButton release];
[dialerButton release];
@@ -56,7 +56,7 @@ static NSString * const kDisappearAnimation = @"disappear";
[historyNotificationLabel release];
[chatNotificationView release];
[chatNotificationLabel release];
-
+
[super dealloc];
}
@@ -65,17 +65,17 @@ static NSString * const kDisappearAnimation = @"disappear";
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
-
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(changeViewEvent:)
+
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(changeViewEvent:)
name:kLinphoneMainViewChange
object:nil];
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(callUpdate:)
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(callUpdate:)
name:kLinphoneCallUpdate
object:nil];
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(textReceived:)
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(textReceived:)
name:kLinphoneTextReceived
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
@@ -87,14 +87,14 @@ static NSString * const kDisappearAnimation = @"disappear";
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
-
- [[NSNotificationCenter defaultCenter] removeObserver:self
+
+ [[NSNotificationCenter defaultCenter] removeObserver:self
name:kLinphoneMainViewChange
object:nil];
- [[NSNotificationCenter defaultCenter] removeObserver:self
+ [[NSNotificationCenter defaultCenter] removeObserver:self
name:kLinphoneCallUpdate
object:nil];
- [[NSNotificationCenter defaultCenter] removeObserver:self
+ [[NSNotificationCenter defaultCenter] removeObserver:self
name:kLinphoneTextReceived
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
@@ -103,35 +103,35 @@ static NSString * const kDisappearAnimation = @"disappear";
}
- (void)viewDidLoad {
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(applicationWillEnterForeground:)
- name:UIApplicationWillEnterForegroundNotification
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(applicationWillEnterForeground:)
+ name:UIApplicationWillEnterForegroundNotification
object:nil];
-
+
{
UIButton *historyButtonLandscape = (UIButton*) [landscapeView viewWithTag:[historyButton tag]];
// Set selected+over background: IB lack !
[historyButton setBackgroundImage:[UIImage imageNamed:@"history_selected.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
-
+
// Set selected+over background: IB lack !
[historyButtonLandscape setBackgroundImage:[UIImage imageNamed:@"history_selected_landscape.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
-
+
[LinphoneUtils buttonFixStatesForTabs:historyButton];
[LinphoneUtils buttonFixStatesForTabs:historyButtonLandscape];
}
-
+
{
UIButton *contactsButtonLandscape = (UIButton*) [landscapeView viewWithTag:[contactsButton tag]];
// Set selected+over background: IB lack !
[contactsButton setBackgroundImage:[UIImage imageNamed:@"contacts_selected.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
-
+
// Set selected+over background: IB lack !
[contactsButtonLandscape setBackgroundImage:[UIImage imageNamed:@"contacts_selected_landscape.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
-
+
[LinphoneUtils buttonFixStatesForTabs:contactsButton];
[LinphoneUtils buttonFixStatesForTabs:contactsButtonLandscape];
}
@@ -140,11 +140,11 @@ static NSString * const kDisappearAnimation = @"disappear";
// Set selected+over background: IB lack !
[dialerButton setBackgroundImage:[UIImage imageNamed:@"dialer_selected.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
-
+
// Set selected+over background: IB lack !
[dialerButtonLandscape setBackgroundImage:[UIImage imageNamed:@"dialer_selected_landscape.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
-
+
[LinphoneUtils buttonFixStatesForTabs:dialerButton];
[LinphoneUtils buttonFixStatesForTabs:dialerButtonLandscape];
}
@@ -153,37 +153,37 @@ static NSString * const kDisappearAnimation = @"disappear";
// Set selected+over background: IB lack !
[settingsButton setBackgroundImage:[UIImage imageNamed:@"settings_selected.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
-
+
// Set selected+over background: IB lack !
[settingsButtonLandscape setBackgroundImage:[UIImage imageNamed:@"settings_selected_landscape.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
-
+
[LinphoneUtils buttonFixStatesForTabs:settingsButton];
[LinphoneUtils buttonFixStatesForTabs:settingsButtonLandscape];
}
-
+
{
UIButton *chatButtonLandscape = (UIButton*) [landscapeView viewWithTag:[chatButton tag]];
// Set selected+over background: IB lack !
[chatButton setBackgroundImage:[UIImage imageNamed:@"chat_selected.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
-
+
// Set selected+over background: IB lack !
[chatButtonLandscape setBackgroundImage:[UIImage imageNamed:@"chat_selected_landscape.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
-
+
[LinphoneUtils buttonFixStatesForTabs:chatButton];
[LinphoneUtils buttonFixStatesForTabs:chatButtonLandscape];
}
-
+
[super viewDidLoad]; // Have to be after due to TPMultiLayoutViewController
}
- (void)viewDidUnload {
[super viewDidUnload];
-
- [[NSNotificationCenter defaultCenter] removeObserver:self
- name:UIApplicationWillEnterForegroundNotification
+
+ [[NSNotificationCenter defaultCenter] removeObserver:self
+ name:UIApplicationWillEnterForegroundNotification
object:nil];
}
@@ -203,8 +203,8 @@ static NSString * const kDisappearAnimation = @"disappear";
#pragma mark - Event Functions
-- (void)applicationWillEnterForeground:(NSNotification*)notif {
- // Force the animations
+- (void)applicationWillEnterForeground:(NSNotification*)notif {
+ // Force the animations
[[self.view layer] removeAllAnimations];
[historyNotificationView.layer setTransform:CATransform3DIdentity];
[chatNotificationView.layer setTransform:CATransform3DIdentity];
@@ -219,7 +219,7 @@ static NSString * const kDisappearAnimation = @"disappear";
[self updateMissedCall:linphone_core_get_missed_calls_count([LinphoneManager getLc]) appear:TRUE];
}
-- (void)changeViewEvent:(NSNotification*)notif {
+- (void)changeViewEvent:(NSNotification*)notif {
//UICompositeViewDescription *view = [notif.userInfo objectForKey: @"view"];
//if(view != nil)
[self updateView:[[PhoneMainView instance] firstView]];
@@ -246,7 +246,7 @@ static NSString * const kDisappearAnimation = @"disappear";
}
-#pragma mark -
+#pragma mark -
- (void)update:(BOOL)appear{
[self updateView:[[PhoneMainView instance] firstView]];
@@ -354,14 +354,14 @@ static NSString * const kDisappearAnimation = @"disappear";
bounce.autoreverses = TRUE;
bounce.repeatCount = HUGE_VALF;
[target.layer addAnimation:bounce forKey:animationID];
-
+
}
- (void)stopBounceAnimation:(NSString *)animationID target:(UIView *)target {
[target.layer removeAnimationForKey:animationID];
}
-
-- (void)updateView:(UICompositeViewDescription*) view {
+
+- (void)updateView:(UICompositeViewDescription*) view {
// Update buttons
if([view equal:[HistoryViewController compositeViewDescription]]) {
historyButton.selected = TRUE;
@@ -401,7 +401,8 @@ static NSString * const kDisappearAnimation = @"disappear";
[ContactSelection setSelectionMode:ContactSelectionModeNone];
[ContactSelection setAddAddress:nil];
[ContactSelection setSipFilter:nil];
- [ContactSelection setEmailFilter:FALSE];
+ [ContactSelection enableEmailFilter:FALSE];
+ [ContactSelection setNameOrEmailFilter:nil];
[[PhoneMainView instance] changeCurrentView:[ContactsViewController compositeViewDescription]];
}
@@ -422,7 +423,7 @@ static NSString * const kDisappearAnimation = @"disappear";
- (NSDictionary*)attributesForView:(UIView*)view {
NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
-
+
[attributes setObject:[NSValue valueWithCGRect:view.frame] forKey:@"frame"];
[attributes setObject:[NSValue valueWithCGRect:view.bounds] forKey:@"bounds"];
if([view isKindOfClass:[UIButton class]]) {
@@ -430,7 +431,7 @@ static NSString * const kDisappearAnimation = @"disappear";
[LinphoneUtils buttonMultiViewAddAttributes:attributes button:button];
}
[attributes setObject:[NSNumber numberWithInteger:view.autoresizingMask] forKey:@"autoresizingMask"];
-
+
return attributes;
}
diff --git a/Classes/LinphoneUI/UIPlusDigitButton.m b/Classes/LinphoneUI/UIPlusDigitButton.m
new file mode 100644
index 000000000..4e3c72211
--- /dev/null
+++ b/Classes/LinphoneUI/UIPlusDigitButton.m
@@ -0,0 +1,12 @@
+//
+// UIPlusDigitButton.m
+// linphone
+//
+// Created by Gautier Pelloux-Prayer on 24/09/14.
+//
+//
+
+#import
+
+@interface UIDigitButton : UILongTouchButton {
+}
\ No newline at end of file
diff --git a/Classes/LinphoneUI/UIStateBar.h b/Classes/LinphoneUI/UIStateBar.h
index 8103c6f37..735cb9bd7 100644
--- a/Classes/LinphoneUI/UIStateBar.h
+++ b/Classes/LinphoneUI/UIStateBar.h
@@ -4,18 +4,18 @@
*
* 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 Library 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
+ * 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 Library 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.
- */
+ */
#import
#import "TPMultiLayoutViewController.h"
@@ -30,7 +30,9 @@
@property (nonatomic, retain) IBOutlet UIImageView* callQualityImage;
@property (nonatomic, retain) IBOutlet UIImageView* callSecurityImage;
@property (nonatomic, retain) IBOutlet UIButton* callSecurityButton;
+@property (retain, nonatomic) IBOutlet UILabel *voicemailCount;
- (IBAction)doSecurityClick:(id)sender;
+
@end
diff --git a/Classes/LinphoneUI/UIStateBar.m b/Classes/LinphoneUI/UIStateBar.m
index 787f07279..a17f149a0 100644
--- a/Classes/LinphoneUI/UIStateBar.m
+++ b/Classes/LinphoneUI/UIStateBar.m
@@ -4,18 +4,18 @@
*
* 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 Library 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
+ * 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 Library 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.
- */
+ */
#import "UIStateBar.h"
#import "LinphoneManager.h"
@@ -36,290 +36,330 @@ NSTimer *callSecurityTimer;
#pragma mark - Lifecycle Functions
- (id)init {
- self = [super initWithNibName:@"UIStateBar" bundle:[NSBundle mainBundle]];
- if(self != nil) {
- self->callSecurityImage = nil;
- self->callQualityImage = nil;
- self->securitySheet = nil;
- }
- return self;
+ self = [super initWithNibName:@"UIStateBar" bundle:[NSBundle mainBundle]];
+ if(self != nil) {
+ self->callSecurityImage = nil;
+ self->callQualityImage = nil;
+ self->securitySheet = nil;
+ }
+ return self;
}
- (void) dealloc {
- if(securitySheet) {
- [securitySheet release];
- }
- [registrationStateImage release];
- [registrationStateLabel release];
- [callQualityImage release];
- [callSecurityImage release];
- [callSecurityButton release];
- [[NSNotificationCenter defaultCenter] removeObserver:self];
- [callQualityTimer invalidate];
- [callQualityTimer release];
- [super dealloc];
+ if(securitySheet) {
+ [securitySheet release];
+ }
+ [registrationStateImage release];
+ [registrationStateLabel release];
+ [callQualityImage release];
+ [callSecurityImage release];
+ [callSecurityButton release];
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+ [callQualityTimer invalidate];
+ [callQualityTimer release];
+ [_voicemailCount release];
+ [super dealloc];
}
#pragma mark - ViewController Functions
- (void)viewWillAppear:(BOOL)animated {
- [super viewWillAppear:animated];
-
- // Set callQualityTimer
- callQualityTimer = [NSTimer scheduledTimerWithTimeInterval:1
- target:self
- selector:@selector(callQualityUpdate)
- userInfo:nil
- repeats:YES];
-
- // Set callQualityTimer
- callSecurityTimer = [NSTimer scheduledTimerWithTimeInterval:1
- target:self
- selector:@selector(callSecurityUpdate)
- userInfo:nil
- repeats:YES];
-
- // Set observer
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(registrationUpdate:)
- name:kLinphoneRegistrationUpdate
- object:nil];
-
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(globalStateUpdate:)
- name:kLinphoneGlobalStateUpdate
- object:nil];
- [callQualityImage setHidden: true];
- [callSecurityImage setHidden: true];
-
- // Update to default state
- LinphoneProxyConfig* config = NULL;
- if([LinphoneManager isLcReady])
- linphone_core_get_default_proxy([LinphoneManager getLc], &config);
- [self proxyConfigUpdate: config];
+ [super viewWillAppear:animated];
+
+ // Set callQualityTimer
+ callQualityTimer = [NSTimer scheduledTimerWithTimeInterval:1
+ target:self
+ selector:@selector(callQualityUpdate)
+ userInfo:nil
+ repeats:YES];
+
+ // Set callQualityTimer
+ callSecurityTimer = [NSTimer scheduledTimerWithTimeInterval:1
+ target:self
+ selector:@selector(callSecurityUpdate)
+ userInfo:nil
+ repeats:YES];
+
+ // Set observer
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(registrationUpdate:)
+ name:kLinphoneRegistrationUpdate
+ object:nil];
+
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(globalStateUpdate:)
+ name:kLinphoneGlobalStateUpdate
+ object:nil];
+
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(notifyReceived:)
+ name:kLinphoneNotifyReceived
+ object:nil];
+
+ [callQualityImage setHidden: true];
+ [callSecurityImage setHidden: true];
+ self.voicemailCount.hidden = true;
+
+ // Update to default state
+ LinphoneProxyConfig* config = NULL;
+ if([LinphoneManager isLcReady])
+ linphone_core_get_default_proxy([LinphoneManager getLc], &config);
+ [self proxyConfigUpdate: config];
}
- (void)viewWillDisappear:(BOOL)animated {
- [super viewWillDisappear:animated];
-
- // Remove observer
- [[NSNotificationCenter defaultCenter] removeObserver:self
- name:kLinphoneRegistrationUpdate
- object:nil];
- [[NSNotificationCenter defaultCenter] removeObserver:self
- name:kLinphoneGlobalStateUpdate
- object:nil];
- if(callQualityTimer != nil) {
- [callQualityTimer invalidate];
- callQualityTimer = nil;
- }
- if(callSecurityTimer != nil) {
- [callSecurityTimer invalidate];
- callSecurityTimer = nil;
- }
+ [super viewWillDisappear:animated];
+
+
+ // Remove observer
+ [[NSNotificationCenter defaultCenter] removeObserver:self
+ name:kLinphoneRegistrationUpdate
+ object:nil];
+ [[NSNotificationCenter defaultCenter] removeObserver:self
+ name:kLinphoneGlobalStateUpdate
+ object:nil];
+ [[NSNotificationCenter defaultCenter] removeObserver:self
+ name:kLinphoneNotifyReceived
+ object:nil];
+ if(callQualityTimer != nil) {
+ [callQualityTimer invalidate];
+ callQualityTimer = nil;
+ }
+ if(callSecurityTimer != nil) {
+ [callSecurityTimer invalidate];
+ callSecurityTimer = nil;
+ }
}
#pragma mark - Event Functions
-- (void)registrationUpdate: (NSNotification*) notif {
- LinphoneProxyConfig* config = NULL;
- linphone_core_get_default_proxy([LinphoneManager getLc], &config);
- [self proxyConfigUpdate:config];
+- (void)registrationUpdate: (NSNotification*) notif {
+ LinphoneProxyConfig* config = NULL;
+ linphone_core_get_default_proxy([LinphoneManager getLc], &config);
+ [self proxyConfigUpdate:config];
}
- (void) globalStateUpdate:(NSNotification*) notif {
- if ([LinphoneManager isLcReady]) [self registrationUpdate:notif];
+ if ([LinphoneManager isLcReady]) [self registrationUpdate:notif];
}
+- (void) notifyReceived:(NSNotification*) notif {
+ const LinphoneContent * content = [[notif.userInfo objectForKey: @"content"] pointerValue];
-#pragma mark -
+ if ((content == NULL)
+ || (strcmp("application", content->type) != 0)
+ || (strcmp("simple-message-summary", content->subtype) != 0)
+ || (content->data == NULL)) {
+ return;
+ }
+
+ const char * body = (const char*) content->data;
+ if ((body = strstr(body, "voice-message: ")) == NULL) {
+ [LinphoneLogger log:LinphoneLoggerWarning format:@"Received new NOTIFY from voice mail but could not find 'voice-message' in BODY. Ignoring it."];
+ return;
+ }
+
+ int unreadCount = 0;
+ sscanf(body, "voice-message: %d", &unreadCount);
+
+ [LinphoneLogger log:LinphoneLoggerLog format:@"Received new NOTIFY from voice mail: there is/are now %d message(s) unread", unreadCount];
+
+ if (unreadCount > 0) {
+ self.voicemailCount.hidden = FALSE;
+ self.voicemailCount.text = [NSString stringWithFormat:NSLocalizedString(@"%d unread messages", @"%d"), unreadCount];
+ } else {
+ self.voicemailCount.hidden = TRUE;
+ }
+}
+
+#pragma mark -
- (void)proxyConfigUpdate: (LinphoneProxyConfig*) config {
- LinphoneRegistrationState state = LinphoneRegistrationNone;
- NSString* message = nil;
- UIImage* image = nil;
- LinphoneCore* lc = [LinphoneManager getLc];
- LinphoneGlobalState gstate = linphone_core_get_global_state(lc);
+ LinphoneRegistrationState state = LinphoneRegistrationNone;
+ NSString* message = nil;
+ UIImage* image = nil;
+ LinphoneCore* lc = [LinphoneManager getLc];
+ LinphoneGlobalState gstate = linphone_core_get_global_state(lc);
- if( gstate == LinphoneGlobalConfiguring ){
- message = NSLocalizedString(@"Fetching remote configuration", nil);
- } else if (config == NULL) {
- state = LinphoneRegistrationNone;
- if(![LinphoneManager isLcReady] || linphone_core_is_network_reachable([LinphoneManager getLc]))
- message = NSLocalizedString(@"No SIP account configured", nil);
- else
- message = NSLocalizedString(@"Network down", nil);
- } else {
- state = linphone_proxy_config_get_state(config);
-
- switch (state) {
- case LinphoneRegistrationOk:
- message = NSLocalizedString(@"Registered", nil); break;
- case LinphoneRegistrationNone:
- case LinphoneRegistrationCleared:
- message = NSLocalizedString(@"Not registered", nil); break;
- case LinphoneRegistrationFailed:
- message = NSLocalizedString(@"Registration failed", nil); break;
- case LinphoneRegistrationProgress:
- message = NSLocalizedString(@"Registration in progress", nil); break;
- default: break;
- }
- }
+ if( gstate == LinphoneGlobalConfiguring ){
+ message = NSLocalizedString(@"Fetching remote configuration", nil);
+ } else if (config == NULL) {
+ state = LinphoneRegistrationNone;
+ if(![LinphoneManager isLcReady] || linphone_core_is_network_reachable([LinphoneManager getLc]))
+ message = NSLocalizedString(@"No SIP account configured", nil);
+ else
+ message = NSLocalizedString(@"Network down", nil);
+ } else {
+ state = linphone_proxy_config_get_state(config);
- registrationStateLabel.hidden = NO;
- switch(state) {
- case LinphoneRegistrationFailed:
- registrationStateImage.hidden = NO;
- image = [UIImage imageNamed:@"led_error.png"];
- break;
- case LinphoneRegistrationCleared:
- case LinphoneRegistrationNone:
- registrationStateImage.hidden = NO;
- image = [UIImage imageNamed:@"led_disconnected.png"];
- break;
- case LinphoneRegistrationProgress:
- registrationStateImage.hidden = NO;
- image = [UIImage imageNamed:@"led_inprogress.png"];
- break;
- case LinphoneRegistrationOk:
- registrationStateImage.hidden = NO;
- image = [UIImage imageNamed:@"led_connected.png"];
- break;
- }
- [registrationStateLabel setText:message];
- [registrationStateImage setImage:image];
+ switch (state) {
+ case LinphoneRegistrationOk:
+ message = NSLocalizedString(@"Registered", nil); break;
+ case LinphoneRegistrationNone:
+ case LinphoneRegistrationCleared:
+ message = NSLocalizedString(@"Not registered", nil); break;
+ case LinphoneRegistrationFailed:
+ message = NSLocalizedString(@"Registration failed", nil); break;
+ case LinphoneRegistrationProgress:
+ message = NSLocalizedString(@"Registration in progress", nil); break;
+ default: break;
+ }
+ }
+
+ registrationStateLabel.hidden = NO;
+ switch(state) {
+ case LinphoneRegistrationFailed:
+ registrationStateImage.hidden = NO;
+ image = [UIImage imageNamed:@"led_error.png"];
+ break;
+ case LinphoneRegistrationCleared:
+ case LinphoneRegistrationNone:
+ registrationStateImage.hidden = NO;
+ image = [UIImage imageNamed:@"led_disconnected.png"];
+ break;
+ case LinphoneRegistrationProgress:
+ registrationStateImage.hidden = NO;
+ image = [UIImage imageNamed:@"led_inprogress.png"];
+ break;
+ case LinphoneRegistrationOk:
+ registrationStateImage.hidden = NO;
+ image = [UIImage imageNamed:@"led_connected.png"];
+ break;
+ }
+ [registrationStateLabel setText:message];
+ [registrationStateImage setImage:image];
}
-#pragma mark -
+#pragma mark -
- (void)callSecurityUpdate {
- BOOL pending = false;
- BOOL security = true;
-
- if(![LinphoneManager isLcReady]) {
- [callSecurityImage setHidden:true];
- return;
- }
- const MSList *list = linphone_core_get_calls([LinphoneManager getLc]);
- if(list == NULL) {
- if(securitySheet) {
- [securitySheet dismissWithClickedButtonIndex:securitySheet.destructiveButtonIndex animated:TRUE];
- }
- [callSecurityImage setHidden:true];
- return;
- }
- while(list != NULL) {
- LinphoneCall *call = (LinphoneCall*) list->data;
- LinphoneMediaEncryption enc = linphone_call_params_get_media_encryption(linphone_call_get_current_params(call));
- if(enc == LinphoneMediaEncryptionNone)
- security = false;
- else if(enc == LinphoneMediaEncryptionZRTP) {
- if(!linphone_call_get_authentication_token_verified(call)) {
- pending = true;
- }
- }
- list = list->next;
- }
-
- if(security) {
- if(pending) {
- [callSecurityImage setImage:[UIImage imageNamed:@"security_pending.png"]];
- } else {
- [callSecurityImage setImage:[UIImage imageNamed:@"security_ok.png"]];
- }
- } else {
- [callSecurityImage setImage:[UIImage imageNamed:@"security_ko.png"]];
- }
- [callSecurityImage setHidden: false];
+ BOOL pending = false;
+ BOOL security = true;
+
+ if(![LinphoneManager isLcReady]) {
+ [callSecurityImage setHidden:true];
+ return;
+ }
+ const MSList *list = linphone_core_get_calls([LinphoneManager getLc]);
+ if(list == NULL) {
+ if(securitySheet) {
+ [securitySheet dismissWithClickedButtonIndex:securitySheet.destructiveButtonIndex animated:TRUE];
+ }
+ [callSecurityImage setHidden:true];
+ return;
+ }
+ while(list != NULL) {
+ LinphoneCall *call = (LinphoneCall*) list->data;
+ LinphoneMediaEncryption enc = linphone_call_params_get_media_encryption(linphone_call_get_current_params(call));
+ if(enc == LinphoneMediaEncryptionNone)
+ security = false;
+ else if(enc == LinphoneMediaEncryptionZRTP) {
+ if(!linphone_call_get_authentication_token_verified(call)) {
+ pending = true;
+ }
+ }
+ list = list->next;
+ }
+
+ if(security) {
+ if(pending) {
+ [callSecurityImage setImage:[UIImage imageNamed:@"security_pending.png"]];
+ } else {
+ [callSecurityImage setImage:[UIImage imageNamed:@"security_ok.png"]];
+ }
+ } else {
+ [callSecurityImage setImage:[UIImage imageNamed:@"security_ko.png"]];
+ }
+ [callSecurityImage setHidden: false];
}
-- (void)callQualityUpdate {
- UIImage *image = nil;
- if([LinphoneManager isLcReady]) {
- LinphoneCall *call = linphone_core_get_current_call([LinphoneManager getLc]);
- if(call != NULL) {
- //FIXME double check call state before computing, may cause core dump
+- (void)callQualityUpdate {
+ UIImage *image = nil;
+ if([LinphoneManager isLcReady]) {
+ LinphoneCall *call = linphone_core_get_current_call([LinphoneManager getLc]);
+ if(call != NULL) {
+ //FIXME double check call state before computing, may cause core dump
float quality = linphone_call_get_average_quality(call);
- if(quality < 1) {
- image = [UIImage imageNamed:@"call_quality_indicator_0.png"];
- } else if (quality < 2) {
- image = [UIImage imageNamed:@"call_quality_indicator_1.png"];
- } else if (quality < 3) {
- image = [UIImage imageNamed:@"call_quality_indicator_2.png"];
- } else {
- image = [UIImage imageNamed:@"call_quality_indicator_3.png"];
- }
- }
- }
- if(image != nil) {
- [callQualityImage setHidden:false];
- [callQualityImage setImage:image];
- } else {
- [callQualityImage setHidden:true];
- }
+ if(quality < 1) {
+ image = [UIImage imageNamed:@"call_quality_indicator_0.png"];
+ } else if (quality < 2) {
+ image = [UIImage imageNamed:@"call_quality_indicator_1.png"];
+ } else if (quality < 3) {
+ image = [UIImage imageNamed:@"call_quality_indicator_2.png"];
+ } else {
+ image = [UIImage imageNamed:@"call_quality_indicator_3.png"];
+ }
+ }
+ }
+ if(image != nil) {
+ [callQualityImage setHidden:false];
+ [callQualityImage setImage:image];
+ } else {
+ [callQualityImage setHidden:true];
+ }
}
#pragma mark - Action Functions
- (IBAction)doSecurityClick:(id)sender {
- if([LinphoneManager isLcReady] && linphone_core_get_calls_nb([LinphoneManager getLc])) {
- LinphoneCall *call = linphone_core_get_current_call([LinphoneManager getLc]);
- if(call != NULL) {
- LinphoneMediaEncryption enc = linphone_call_params_get_media_encryption(linphone_call_get_current_params(call));
- if(enc == LinphoneMediaEncryptionZRTP) {
- bool valid = linphone_call_get_authentication_token_verified(call);
- NSString *message = nil;
- if(valid) {
- message = NSLocalizedString(@"Remove trust in the peer?",nil);
- } else {
- message = [NSString stringWithFormat:NSLocalizedString(@"Confirm the following SAS with the peer:\n%s",nil),
- linphone_call_get_authentication_token(call)];
- }
- if( securitySheet == nil ){
- securitySheet = [[DTActionSheet alloc] initWithTitle:message];
- [securitySheet setDelegate:self];
- [securitySheet addButtonWithTitle:NSLocalizedString(@"Ok",nil) block:^(){
- linphone_call_set_authentication_token_verified(call, !valid);
- [securitySheet release];
- securitySheet = nil;
- }];
+ if([LinphoneManager isLcReady] && linphone_core_get_calls_nb([LinphoneManager getLc])) {
+ LinphoneCall *call = linphone_core_get_current_call([LinphoneManager getLc]);
+ if(call != NULL) {
+ LinphoneMediaEncryption enc = linphone_call_params_get_media_encryption(linphone_call_get_current_params(call));
+ if(enc == LinphoneMediaEncryptionZRTP) {
+ bool valid = linphone_call_get_authentication_token_verified(call);
+ NSString *message = nil;
+ if(valid) {
+ message = NSLocalizedString(@"Remove trust in the peer?",nil);
+ } else {
+ message = [NSString stringWithFormat:NSLocalizedString(@"Confirm the following SAS with the peer:\n%s",nil),
+ linphone_call_get_authentication_token(call)];
+ }
+ if( securitySheet == nil ){
+ securitySheet = [[DTActionSheet alloc] initWithTitle:message];
+ [securitySheet setDelegate:self];
+ [securitySheet addButtonWithTitle:NSLocalizedString(@"Ok",nil) block:^(){
+ linphone_call_set_authentication_token_verified(call, !valid);
+ [securitySheet release];
+ securitySheet = nil;
+ }];
- [securitySheet addDestructiveButtonWithTitle:NSLocalizedString(@"Cancel",nil) block:^(){
- [securitySheet release];
- securitySheet = nil;
- }];
- [securitySheet showInView:[PhoneMainView instance].view];
- }
- }
- }
- }
+ [securitySheet addDestructiveButtonWithTitle:NSLocalizedString(@"Cancel",nil) block:^(){
+ [securitySheet release];
+ securitySheet = nil;
+ }];
+ [securitySheet showInView:[PhoneMainView instance].view];
+ }
+ }
+ }
+ }
}
-(void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex{
- [securitySheet release];
- securitySheet = nil;
+ [securitySheet release];
+ securitySheet = nil;
}
#pragma mark - TPMultiLayoutViewController Functions
- (NSDictionary*)attributesForView:(UIView*)view {
- NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
-
- [attributes setObject:[NSValue valueWithCGRect:view.frame] forKey:@"frame"];
- [attributes setObject:[NSValue valueWithCGRect:view.bounds] forKey:@"bounds"];
- [attributes setObject:[NSNumber numberWithInteger:view.autoresizingMask] forKey:@"autoresizingMask"];
-
- return attributes;
+ NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
+
+ [attributes setObject:[NSValue valueWithCGRect:view.frame] forKey:@"frame"];
+ [attributes setObject:[NSValue valueWithCGRect:view.bounds] forKey:@"bounds"];
+ [attributes setObject:[NSNumber numberWithInteger:view.autoresizingMask] forKey:@"autoresizingMask"];
+
+ return attributes;
}
- (void)applyAttributes:(NSDictionary*)attributes toView:(UIView*)view {
- view.frame = [[attributes objectForKey:@"frame"] CGRectValue];
- view.bounds = [[attributes objectForKey:@"bounds"] CGRectValue];
- view.autoresizingMask = [[attributes objectForKey:@"autoresizingMask"] integerValue];
+ view.frame = [[attributes objectForKey:@"frame"] CGRectValue];
+ view.bounds = [[attributes objectForKey:@"bounds"] CGRectValue];
+ view.autoresizingMask = [[attributes objectForKey:@"autoresizingMask"] integerValue];
}
@end
diff --git a/Classes/LinphoneUI/UIStateBar.xib b/Classes/LinphoneUI/UIStateBar.xib
index 947d5629b..59d49c22d 100644
--- a/Classes/LinphoneUI/UIStateBar.xib
+++ b/Classes/LinphoneUI/UIStateBar.xib
@@ -1,8 +1,8 @@
-
+
-
-
+
+
@@ -15,6 +15,7 @@
+
@@ -69,8 +70,17 @@
+
+
+
@@ -114,12 +124,26 @@
+
+
+
-
\ No newline at end of file
+
+
+
+
+
+
diff --git a/Classes/MainStoryboard.storyboard b/Classes/MainStoryboard.storyboard
new file mode 100644
index 000000000..dc493538e
--- /dev/null
+++ b/Classes/MainStoryboard.storyboard
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Classes/PhoneMainView.h b/Classes/PhoneMainView.h
index 0c1f5edb9..f6a09756a 100644
--- a/Classes/PhoneMainView.h
+++ b/Classes/PhoneMainView.h
@@ -23,6 +23,7 @@
#import "LinphoneManager.h"
#import "UICompositeViewController.h"
+/* These imports are here so that we can import PhoneMainView.h without bothering to import all the rest of the view headers */
#import "AboutViewController.h"
#import "FirstLoginViewController.h"
#import "IncomingCallViewController.h"
@@ -43,10 +44,23 @@
#import "ConsoleViewController.h"
#import "ImageViewController.h"
+
+@class PhoneMainView;
+
+@interface RootViewManager : NSObject
+
+@property (nonatomic, retain) PhoneMainView* portraitViewController;
+@property (nonatomic, retain) PhoneMainView* rotatingViewController;
+@property (nonatomic, retain) NSMutableArray* viewDescriptionStack;
+
++(RootViewManager*)instance;
++ (void)setupWithPortrait:(PhoneMainView*)portrait;
+- (PhoneMainView*)currentView;
+
+@end
+
@interface PhoneMainView : UIViewController {
@private
- int loadCount;
- NSMutableArray *viewStack;
NSMutableArray *inhibitedEvents;
NSTimer *batteryTimer;
}
@@ -54,6 +68,7 @@
@property (nonatomic, retain) IBOutlet UIView *statusBarBG;
@property (nonatomic, retain) IBOutlet UICompositeViewController *mainViewController;
+@property (nonatomic, retain) NSString* name;
@property (readonly) UICompositeViewDescription *currentView;
@property (readonly, retain) MPVolumeView* volumeView;
@@ -73,6 +88,7 @@
- (void)addInhibitedEvent:(id)event;
- (BOOL)removeInhibitedEvent:(id)event;
+- (void)updateApplicationBadgeNumber;
+ (PhoneMainView*) instance;
@end
diff --git a/Classes/PhoneMainView.m b/Classes/PhoneMainView.m
index d360fa9b6..d5b78c37e 100644
--- a/Classes/PhoneMainView.m
+++ b/Classes/PhoneMainView.m
@@ -25,7 +25,83 @@
#import "Utils.h"
#import "DTActionSheet.h"
-static PhoneMainView* phoneMainViewInstance=nil;
+
+static RootViewManager* rootViewManagerInstance = nil;
+
+@implementation RootViewManager {
+ PhoneMainView* currentViewController;
+}
+
++ (void)setupWithPortrait:(PhoneMainView*)portrait {
+ assert(rootViewManagerInstance == nil);
+ rootViewManagerInstance = [[RootViewManager alloc]initWithPortrait:portrait];
+}
+
+- (instancetype)initWithPortrait:(PhoneMainView*)portrait {
+ self = [super init];
+ if ( self ){
+ self.portraitViewController = portrait;
+ self.rotatingViewController = [[[PhoneMainView alloc] init] autorelease];
+
+ self.portraitViewController.name = @"Portrait";
+ self.rotatingViewController.name = @"Rotating";
+
+ currentViewController = portrait;
+ self.viewDescriptionStack = [NSMutableArray array];
+
+ }
+ return self;
+}
+
++ (RootViewManager *)instance {
+ if( !rootViewManagerInstance ){
+ @throw [NSException exceptionWithName:@"RootViewManager" reason:@"nil instance" userInfo:nil];
+ }
+ return rootViewManagerInstance;
+}
+
+- (PhoneMainView*)currentView {
+ return currentViewController;
+}
+
+- (PhoneMainView*)setViewControllerForDescription:(UICompositeViewDescription*)description {
+ PhoneMainView* newMainView = description.landscapeMode ? self.rotatingViewController : self.portraitViewController;
+
+ if( [LinphoneManager runningOnIpad] ) return currentViewController;
+
+ if( newMainView != currentViewController )
+ {
+ PhoneMainView* previousMainView = currentViewController;
+ UIInterfaceOrientation nextViewOrientation = newMainView.interfaceOrientation;
+ UIInterfaceOrientation previousOrientation = currentViewController.interfaceOrientation;
+
+ Linphone_err(@"Changing rootViewController: %@ -> %@", currentViewController.name, newMainView.name);
+ currentViewController = newMainView;
+ LinphoneAppDelegate* delegate = (LinphoneAppDelegate*)[UIApplication sharedApplication].delegate;
+
+ [UIView transitionWithView:delegate.window
+ duration:0.3
+ options:UIViewAnimationOptionTransitionFlipFromLeft|UIViewAnimationOptionAllowAnimatedContent
+ animations:^{
+ delegate.window.rootViewController = newMainView;
+ // when going to landscape-enabled view, we have to get the current portrait frame and orientation,
+ // because it could still have landscape-based size
+ if( nextViewOrientation != previousOrientation && newMainView == self.rotatingViewController ){
+ newMainView.view.frame = previousMainView.view.frame;
+ [newMainView.mainViewController.view setFrame:previousMainView.mainViewController.view.frame];
+ [newMainView willRotateToInterfaceOrientation:previousOrientation duration:0.3];
+ [newMainView willAnimateRotationToInterfaceOrientation:previousOrientation duration:0.3];
+ [newMainView didRotateFromInterfaceOrientation:nextViewOrientation];
+ }
+
+ }
+ completion:^(BOOL finished) {
+ }];
+ }
+ return currentViewController;
+}
+
+@end
@implementation PhoneMainView
@@ -38,11 +114,7 @@ static PhoneMainView* phoneMainViewInstance=nil;
#pragma mark - Lifecycle Functions
- (void)initPhoneMainView {
- assert (!phoneMainViewInstance);
- phoneMainViewInstance = self;
currentView = nil;
- viewStack = [[NSMutableArray alloc] init];
- loadCount = 0; // For avoiding IOS 4 bug
inhibitedEvents = [[NSMutableArray alloc] init];
}
@@ -75,7 +147,6 @@ static PhoneMainView* phoneMainViewInstance=nil;
[mainViewController release];
[inhibitedEvents release];
- [viewStack release];
[super dealloc];
}
@@ -84,26 +155,21 @@ static PhoneMainView* phoneMainViewInstance=nil;
#pragma mark - ViewController Functions
- (void)viewDidLoad {
- // Avoid IOS 4 bug
- if(loadCount++ > 0)
- return;
-
[super viewDidLoad];
volumeView = [[MPVolumeView alloc] initWithFrame: CGRectMake(-100,-100,16,16)];
volumeView.showsRouteButton = false;
volumeView.userInteractionEnabled = false;
- [self.view addSubview: mainViewController.view];
+ [self.view addSubview:mainViewController.view];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
-
+
if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) {
[mainViewController viewWillAppear:animated];
- }
-
+ }
// Set observers
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(callUpdate:)
@@ -132,7 +198,7 @@ static PhoneMainView* phoneMainViewInstance=nil;
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
-
+
if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) {
[mainViewController viewWillDisappear:animated];
}
@@ -174,9 +240,6 @@ static PhoneMainView* phoneMainViewInstance=nil;
- (void)viewDidUnload {
[super viewDidUnload];
-
- // Avoid IOS 4 bug
- loadCount--;
}
- (void)setVolumeHidden:(BOOL)hidden {
@@ -193,14 +256,13 @@ static PhoneMainView* phoneMainViewInstance=nil;
}
}
-- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
- if(interfaceOrientation == self.interfaceOrientation)
- return YES;
- return NO;
-}
- (NSUInteger)supportedInterfaceOrientations {
- return 0;
+ if( [LinphoneManager runningOnIpad ] || [mainViewController currentViewSupportsLandscape] )
+ return UIInterfaceOrientationMaskAll;
+ else {
+ return UIInterfaceOrientationMaskPortrait;
+ }
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
@@ -225,7 +287,7 @@ static PhoneMainView* phoneMainViewInstance=nil;
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
- [mainViewController clearCache:viewStack];
+ [mainViewController clearCache:[RootViewManager instance].viewDescriptionStack];
}
#pragma mark - Event Functions
@@ -449,7 +511,7 @@ static PhoneMainView* phoneMainViewInstance=nil;
}
+ (PhoneMainView *) instance {
- return phoneMainViewInstance;
+ return [[RootViewManager instance] currentView];
}
- (void) showTabBar:(BOOL)show {
@@ -460,18 +522,11 @@ static PhoneMainView* phoneMainViewInstance=nil;
[mainViewController setStateBarHidden:!show];
}
-+ (BOOL)isDarkBackgroundView:(UICompositeViewDescription*)view {
- return ( [view equal:[DialerViewController compositeViewDescription]] ||
- [view equal:[IncomingCallViewController compositeViewDescription]] ||
- [view equal:[InCallViewController compositeViewDescription]] ||
- [view equal:[WizardViewController compositeViewDescription]]);
-}
-
- (void)updateStatusBar:(UICompositeViewDescription*)to_view {
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
// In iOS7, the app has a black background on dialer, incoming and incall, so we have to adjust the
// status bar style for each transition to/from these views
- BOOL toLightStatus = (to_view != NULL) && ![PhoneMainView isDarkBackgroundView:to_view];
+ BOOL toLightStatus = (to_view != NULL) && ![to_view darkBackground];
if( !toLightStatus ) {
// black bg: white text on black background
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
@@ -502,7 +557,8 @@ static PhoneMainView* phoneMainViewInstance=nil;
- (UIViewController*)changeCurrentView:(UICompositeViewDescription*)view push:(BOOL)push {
BOOL force = push;
- if(!push) {
+ NSMutableArray* viewStack = [RootViewManager instance].viewDescriptionStack;
+ if(!push ) {
force = [viewStack count] > 1;
[viewStack removeAllObjects];
}
@@ -512,27 +568,32 @@ static PhoneMainView* phoneMainViewInstance=nil;
- (UIViewController*)_changeCurrentView:(UICompositeViewDescription*)view transition:(CATransition*)transition force:(BOOL)force {
[LinphoneLogger logc:LinphoneLoggerLog format:"PhoneMainView: Change current view to %@", [view name]];
-
- if(force || ![view equal: currentView]) {
+
+ PhoneMainView* vc = [[RootViewManager instance] setViewControllerForDescription:view];
+
+ if(force || ![view equal:vc.currentView] || vc != self) {
if(transition == nil)
- transition = [PhoneMainView getTransition:currentView new:view];
+ transition = [PhoneMainView getTransition:vc.currentView new:view];
if ([[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"] == true) {
- [mainViewController setViewTransition:transition];
+ [vc.mainViewController setViewTransition:transition];
} else {
- [mainViewController setViewTransition:nil];
+ [vc.mainViewController setViewTransition:nil];
}
- [self updateStatusBar:view];
- [mainViewController changeView:view];
- currentView = view;
+ [vc updateStatusBar:view];
+ [vc.mainViewController changeView:view];
+ vc->currentView = view;
}
+
+ //[[RootViewManager instance] setViewControllerForDescription:view];
- NSDictionary* mdict = [NSMutableDictionary dictionaryWithObject:currentView forKey:@"view"];
+ NSDictionary* mdict = [NSMutableDictionary dictionaryWithObject:vc->currentView forKey:@"view"];
[[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneMainViewChange object:self userInfo:mdict];
- return [mainViewController getCurrentViewController];
+ return [vc->mainViewController getCurrentViewController];
}
- (void)popToView:(UICompositeViewDescription*)view {
+ NSMutableArray* viewStack = [RootViewManager instance].viewDescriptionStack;
while([viewStack count] > 1 && ![[viewStack lastObject] equal:view]) {
[viewStack removeLastObject];
}
@@ -541,7 +602,8 @@ static PhoneMainView* phoneMainViewInstance=nil;
- (UICompositeViewDescription *)firstView {
UICompositeViewDescription *view = nil;
- if([viewStack count]) {
+ NSArray* viewStack = [RootViewManager instance].viewDescriptionStack;
+ if([viewStack count]) {
view = [viewStack objectAtIndex:0];
}
return view;
@@ -549,7 +611,8 @@ static PhoneMainView* phoneMainViewInstance=nil;
- (UIViewController*)popCurrentView {
[LinphoneLogger logc:LinphoneLoggerLog format:"PhoneMainView: Pop view"];
- if([viewStack count] > 1) {
+ NSMutableArray* viewStack = [RootViewManager instance].viewDescriptionStack;
+ if([viewStack count] > 1) {
[viewStack removeLastObject];
[self _changeCurrentView:[viewStack lastObject] transition:[PhoneMainView getBackwardTransition] force:TRUE];
return [mainViewController getCurrentViewController];
diff --git a/Classes/SettingsViewController.m b/Classes/SettingsViewController.m
index 702df5c96..af73214e2 100644
--- a/Classes/SettingsViewController.m
+++ b/Classes/SettingsViewController.m
@@ -630,7 +630,7 @@ static UICompositeViewDescription *compositeDescription = nil;
- (NSSet*)findHiddenKeys {
if(![LinphoneManager isLcReady]) {
- [LinphoneLogger log:LinphoneLoggerWarning format:@"Can't filter settings: Linphone core not read"];
+ [LinphoneLogger log:LinphoneLoggerWarning format:@"Can't filter settings: Linphone core not ready"];
}
LinphoneManager* lm = [LinphoneManager instance];
NSMutableSet *hiddenKeys = [NSMutableSet set];
diff --git a/Classes/Utils/DTFoundation/DTActionSheet.h b/Classes/Utils/DTFoundation/DTActionSheet.h
index 71ab47650..b08744656 100755
--- a/Classes/Utils/DTFoundation/DTActionSheet.h
+++ b/Classes/Utils/DTFoundation/DTActionSheet.h
@@ -6,45 +6,63 @@
// Copyright (c) 2012 Cocoanetics. All rights reserved.
//
+#import "DTWeakSupport.h"
+
+// the block to execute when an option button is tapped
typedef void (^DTActionSheetBlock)(void);
/**
- Extends UIActionSheet with support for blocks
+ Extends UIActionSheet with support for blocks.
*/
@interface DTActionSheet : UIActionSheet
/**
- Initializes the action sheet using the specified title.
+ Initializes the action sheet using the specified title.
+ @param title The title
*/
-- (id)initWithTitle:(NSString *)title;
+- (instancetype)initWithTitle:(NSString *)title;
/**
Adds a custom button to the action sheet.
@param title The title of the new button.
@param block The block to execute when the button is tapped.
@returns The index of the new button. Button indices start at 0 and increase in the order they are added.
-*/
+ */
- (NSInteger)addButtonWithTitle:(NSString *)title block:(DTActionSheetBlock)block;
/**
Adds a custom destructive button to the action sheet.
-
+
Since there can only be one destructive button a previously marked destructive button becomes a normal button.
@param title The title of the new button.
@param block The block to execute when the button is tapped.
@returns The index of the new button. Button indices start at 0 and increase in the order they are added.
- */
+ */
- (NSInteger)addDestructiveButtonWithTitle:(NSString *)title block:(DTActionSheetBlock)block;
/**
Adds a custom cancel button to the action sheet.
-
+
Since there can only be one cancel button a previously marked cancel button becomes a normal button.
@param title The title of the new button.
@param block The block to execute when the button is tapped.
@returns The index of the new button. Button indices start at 0 and increase in the order they are added.
- */
+ */
- (NSInteger)addCancelButtonWithTitle:(NSString *)title block:(DTActionSheetBlock)block;
-@end
+/**
+ Adds a custom cancel button to the action sheet.
+
+ Since there can only be one cancel button a previously marked cancel button becomes a normal button.
+ @param title The title of the new button.
+ @returns The index of the new button. Button indices start at 0 and increase in the order they are added.
+ */
+- (NSInteger)addCancelButtonWithTitle:(NSString *)title;
+
+/**
+ * Use the actionSheetDelegate when you want to to receive UIActionSheetDelegate messages.
+ */
+@property (nonatomic, DT_WEAK_PROPERTY) id actionSheetDelegate;
+
+@end
\ No newline at end of file
diff --git a/Classes/Utils/DTFoundation/DTActionSheet.m b/Classes/Utils/DTFoundation/DTActionSheet.m
index f3a474c75..ae091c824 100755
--- a/Classes/Utils/DTFoundation/DTActionSheet.m
+++ b/Classes/Utils/DTFoundation/DTActionSheet.m
@@ -7,6 +7,7 @@
//
#import "DTActionSheet.h"
+#import "DTWeakSupport.h"
@interface DTActionSheet ()
@@ -14,55 +15,74 @@
@implementation DTActionSheet
{
- id _externalDelegate;
-
NSMutableDictionary *_actionsPerIndex;
-
- // lookup bitmask what delegate methods are implemented
- struct
- {
- unsigned int delegateSupportsActionSheetCancel:1;
- unsigned int delegateSupportsWillPresentActionSheet:1;
- unsigned int delegateSupportsDidPresentActionSheet:1;
- unsigned int delegateSupportsWillDismissWithButtonIndex:1;
- unsigned int delegateSupportsDidDismissWithButtonIndex:1;
- } _delegateFlags;
}
-- (id)init
+// designated initializer
+- (instancetype)init
{
self = [super init];
if (self)
{
_actionsPerIndex = [[NSMutableDictionary alloc] init];
- self.delegate = self;
+ [super setDelegate:self];
+
}
-
return self;
}
-// designated initializer
-- (id)initWithTitle:(NSString *)title
+- (instancetype)initWithTitle:(NSString *)title
+{
+ return [self initWithTitle:title delegate:nil cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
+}
+
+- (instancetype)initWithTitle:(NSString *)title delegate:(id)delegate cancelButtonTitle:(NSString *)cancelButtonTitle destructiveButtonTitle:(NSString *)destructiveButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ...
{
self = [self init];
- if (self)
+ if (self)
{
self.title = title;
+
+ if (otherButtonTitles != nil) {
+ [self addButtonWithTitle:otherButtonTitles];
+ va_list args;
+ va_start(args, otherButtonTitles);
+ NSString *title = nil;
+ while( (title = va_arg(args, NSString *)) ) {
+ [self addButtonWithTitle:title];
+ }
+ va_end(args);
+ }
+
+ if (destructiveButtonTitle) {
+ [self addDestructiveButtonWithTitle:destructiveButtonTitle block:nil];
+ }
+ if (cancelButtonTitle) {
+ [self addCancelButtonWithTitle:cancelButtonTitle block:nil];
+ }
+
+ self.actionSheetDelegate = delegate;
}
-
+
return self;
}
+- (void)dealloc
+{
+ [super setDelegate:nil];
+ self.actionSheetDelegate = nil;
+}
+
- (NSInteger)addButtonWithTitle:(NSString *)title block:(DTActionSheetBlock)block
{
NSInteger retIndex = [self addButtonWithTitle:title];
-
+
if (block)
{
- NSNumber *key = [NSNumber numberWithInt:retIndex];
- [_actionsPerIndex setObject:[[block copy] autorelease] forKey:key];
+ NSNumber *key = [NSNumber numberWithInteger:retIndex];
+ [_actionsPerIndex setObject:[block copy] forKey:key];
}
-
+
return retIndex;
}
@@ -70,122 +90,90 @@
{
NSInteger retIndex = [self addButtonWithTitle:title block:block];
[self setDestructiveButtonIndex:retIndex];
-
+
return retIndex;
}
+- (NSInteger)addCancelButtonWithTitle:(NSString *)title
+{
+ return [self addCancelButtonWithTitle:title block:nil];
+}
+
- (NSInteger)addCancelButtonWithTitle:(NSString *)title block:(DTActionSheetBlock)block
{
NSInteger retIndex = [self addButtonWithTitle:title block:block];
[self setCancelButtonIndex:retIndex];
-
+
return retIndex;
}
-#pragma UIActionSheetDelegate (forwarded)
+#pragma mark - UIActionSheetDelegate (forwarded)
- (void)actionSheetCancel:(UIActionSheet *)actionSheet
{
- if (_delegateFlags.delegateSupportsActionSheetCancel)
+ if ([self.actionSheetDelegate respondsToSelector:@selector(actionSheetCancel:)])
{
- [_externalDelegate actionSheetCancel:actionSheet];
+ [self.actionSheetDelegate actionSheetCancel:actionSheet];
}
}
- (void)willPresentActionSheet:(UIActionSheet *)actionSheet
{
- if (_delegateFlags.delegateSupportsWillPresentActionSheet)
+ if ([self.actionSheetDelegate respondsToSelector:@selector(willPresentActionSheet:)])
{
- [_externalDelegate willPresentActionSheet:actionSheet];
+ [self.actionSheetDelegate willPresentActionSheet:actionSheet];
}
}
- (void)didPresentActionSheet:(UIActionSheet *)actionSheet
{
- if (_delegateFlags.delegateSupportsDidPresentActionSheet)
+ if ([self.actionSheetDelegate respondsToSelector:@selector(didPresentActionSheet:)])
{
- [_externalDelegate didPresentActionSheet:actionSheet];
+ [self.actionSheetDelegate didPresentActionSheet:actionSheet];
}
}
- (void)actionSheet:(UIActionSheet *)actionSheet willDismissWithButtonIndex:(NSInteger)buttonIndex
{
- if (_delegateFlags.delegateSupportsWillDismissWithButtonIndex)
+ if ([self.actionSheetDelegate respondsToSelector:@selector(actionSheet:willDismissWithButtonIndex:)])
{
- [_externalDelegate actionSheet:actionSheet willDismissWithButtonIndex:buttonIndex];
+ [self.actionSheetDelegate actionSheet:actionSheet willDismissWithButtonIndex:buttonIndex];
}
}
-
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
{
- NSNumber *key = [NSNumber numberWithInt:buttonIndex];
-
+ if ([self.actionSheetDelegate respondsToSelector:@selector(actionSheet:didDismissWithButtonIndex:)])
+ {
+ [self.actionSheetDelegate actionSheet:actionSheet didDismissWithButtonIndex:buttonIndex];
+ }
+}
+
+- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+ NSNumber *key = [NSNumber numberWithInteger:buttonIndex];
+
DTActionSheetBlock block = [_actionsPerIndex objectForKey:key];
-
+
if (block)
{
block();
}
- if (_delegateFlags.delegateSupportsDidDismissWithButtonIndex)
+ if ([self.actionSheetDelegate respondsToSelector:@selector(actionSheet:clickedButtonAtIndex:)])
{
- [_externalDelegate actionSheet:actionSheet didDismissWithButtonIndex:buttonIndex];
+ [self.actionSheetDelegate actionSheet:actionSheet clickedButtonAtIndex:buttonIndex];
}
}
-
-#pragma mark Properties
-
-- (id )delegate
-{
- return _externalDelegate;
-}
+#pragma mark - Properties
- (void)setDelegate:(id )delegate
{
- if (delegate == self)
+ if (delegate)
{
- [super setDelegate:self];
- }
- else if (delegate == nil)
- {
- [super setDelegate:nil];
- _externalDelegate = nil;
- }
- else
- {
- _externalDelegate = delegate;
- }
-
- // wipe
- memset(&_delegateFlags, 0, sizeof(_delegateFlags));
-
- // set flags according to available methods in delegate
- if ([_externalDelegate respondsToSelector:@selector(actionSheetCancel:)])
- {
- _delegateFlags.delegateSupportsActionSheetCancel = YES;
- }
-
- if ([_externalDelegate respondsToSelector:@selector(willPresentActionSheet:)])
- {
- _delegateFlags.delegateSupportsWillPresentActionSheet = YES;
- }
-
- if ([_externalDelegate respondsToSelector:@selector(didPresentActionSheet:)])
- {
- _delegateFlags.delegateSupportsDidPresentActionSheet = YES;
- }
-
- if ([_externalDelegate respondsToSelector:@selector(actionSheet:willDismissWithButtonIndex:)])
- {
- _delegateFlags.delegateSupportsWillDismissWithButtonIndex = YES;
- }
-
- if ([_externalDelegate respondsToSelector:@selector(actionSheet:didDismissWithButtonIndex:)])
- {
- _delegateFlags.delegateSupportsDidDismissWithButtonIndex = YES;
+ NSLog(@"Calling setDelegate is not supported! Use setActionSheetDelegate instead");
}
}
-@end
+@end
\ No newline at end of file
diff --git a/Classes/Utils/DTFoundation/DTWeakSupport.h b/Classes/Utils/DTFoundation/DTWeakSupport.h
new file mode 100644
index 000000000..a74444baf
--- /dev/null
+++ b/Classes/Utils/DTFoundation/DTWeakSupport.h
@@ -0,0 +1,33 @@
+//
+// DTWeakSupport.h
+// DTFoundation
+//
+// Created by Oliver Drobnik on 6/3/13.
+// Copyright (c) 2013 Cocoanetics. All rights reserved.
+//
+
+/**
+ Useful defines for building code the compiles with zeroing weak references if the deployment target allows it. This is possible from minimum supported iOS 5.0 and OS X 10.7 and above. Note that on OS X 10.7 some AppKit classes do not support having a weak ref, e.g. NSWindowController or NSViewController.
+ */
+
+#import
+
+#if __has_feature(objc_arc_weak)
+
+// zeroing weak refs are supported for ivars and properties
+#define DT_WEAK_VARIABLE __weak
+#define DT_WEAK_PROPERTY weak
+
+#elif __has_feature(objc_arc)
+
+/// zeroing weak refs not supported, fall back to unsafe unretained and assigning
+#define DT_WEAK_VARIABLE __unsafe_unretained
+#define DT_WEAK_PROPERTY assign
+
+#else
+
+// define something, as this header might be included in a non-ARC project for using compiled code from an ARC static lib
+#define DT_WEAK_VARIABLE
+#define DT_WEAK_PROPERTY assign
+
+#endif
\ No newline at end of file
diff --git a/Classes/Utils/Utils.h b/Classes/Utils/Utils.h
index 9b2b36a78..28b950d5d 100644
--- a/Classes/Utils/Utils.h
+++ b/Classes/Utils/Utils.h
@@ -27,8 +27,8 @@
})
typedef enum _LinphoneLoggerSeverity {
- LinphoneLoggerLog = 0,
- LinphoneLoggerDebug,
+ LinphoneLoggerDebug = 0,
+ LinphoneLoggerLog,
LinphoneLoggerWarning,
LinphoneLoggerError,
LinphoneLoggerFatal
diff --git a/Classes/WizardViewController.m b/Classes/WizardViewController.m
index 0609bf960..5e3313f13 100644
--- a/Classes/WizardViewController.m
+++ b/Classes/WizardViewController.m
@@ -129,6 +129,7 @@ static UICompositeViewDescription *compositeDescription = nil;
fullscreen:false
landscapeMode:[LinphoneManager runningOnIpad]
portraitMode:true];
+ compositeDescription.darkBackground = true;
}
return compositeDescription;
}
@@ -917,7 +918,8 @@ static UICompositeViewDescription *compositeDescription = nil;
[UIView setAnimationCurve:curve];
[UIView setAnimationBeginsFromCurrentState:TRUE];
- if(UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) {
+ if(([[UIDevice currentDevice].systemVersion floatValue] < 8) &&
+ UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) {
int width = endFrame.size.height;
endFrame.size.height = endFrame.size.width;
endFrame.size.width = width;
diff --git a/LinphoneTester Tests/DTObjectBlockExecutor.h b/LinphoneTester Tests/DTObjectBlockExecutor.h
new file mode 100644
index 000000000..19926d805
--- /dev/null
+++ b/LinphoneTester Tests/DTObjectBlockExecutor.h
@@ -0,0 +1,26 @@
+//
+// DTObjectBlockExecutor.h
+// DTFoundation
+//
+// Created by Oliver Drobnik on 12.02.13.
+// Copyright (c) 2013 Cocoanetics. All rights reserved.
+//
+
+/**
+ This class is used by [NSObject addDeallocBlock:] to execute blocks on dealloc
+ */
+
+@interface DTObjectBlockExecutor : NSObject
+
+/**
+ Convenience method to create a block executor with a deallocation block
+ @param block The block to execute when the created receiver is being deallocated
+ */
++ (id)blockExecutorWithDeallocBlock:(void(^)())block;
+
+/**
+ Block to execute when dealloc of the receiver is called
+ */
+@property (nonatomic, copy) void (^deallocBlock)();
+
+@end
diff --git a/LinphoneTester Tests/DTObjectBlockExecutor.m b/LinphoneTester Tests/DTObjectBlockExecutor.m
new file mode 100644
index 000000000..4e9dfd0fd
--- /dev/null
+++ b/LinphoneTester Tests/DTObjectBlockExecutor.m
@@ -0,0 +1,30 @@
+//
+// DTObjectBlockExecutor.m
+// DTFoundation
+//
+// Created by Oliver Drobnik on 12.02.13.
+// Copyright (c) 2013 Cocoanetics. All rights reserved.
+//
+
+#import "DTObjectBlockExecutor.h"
+
+
+@implementation DTObjectBlockExecutor
+
++ (id)blockExecutorWithDeallocBlock:(void(^)())block
+{
+ DTObjectBlockExecutor *executor = [[DTObjectBlockExecutor alloc] init];
+ executor.deallocBlock = block; // copy
+ return executor;
+}
+
+- (void)dealloc
+{
+ if (_deallocBlock)
+ {
+ _deallocBlock();
+ _deallocBlock = nil;
+ }
+}
+
+@end
diff --git a/LinphoneTesterTests/LinphoneTesterTests-Info.plist b/LinphoneTester Tests/LinphoneTester Tests-Info.plist
similarity index 100%
rename from LinphoneTesterTests/LinphoneTesterTests-Info.plist
rename to LinphoneTester Tests/LinphoneTester Tests-Info.plist
diff --git a/LinphoneTester Tests/LinphoneTester Tests-Prefix.pch b/LinphoneTester Tests/LinphoneTester Tests-Prefix.pch
new file mode 100644
index 000000000..b5ffd7806
--- /dev/null
+++ b/LinphoneTester Tests/LinphoneTester Tests-Prefix.pch
@@ -0,0 +1,10 @@
+//
+// Prefix header
+//
+// The contents of this file are implicitly included at the beginning of every source file.
+//
+
+#ifdef __OBJC__
+ #import
+ #import
+#endif
diff --git a/LinphoneTester Tests/LinphoneTester_Tests.m b/LinphoneTester Tests/LinphoneTester_Tests.m
new file mode 100644
index 000000000..b4631e2a0
--- /dev/null
+++ b/LinphoneTester Tests/LinphoneTester_Tests.m
@@ -0,0 +1,106 @@
+//
+// LinphoneTester_Tests.m
+// LinphoneTester Tests
+//
+// Created by guillaume on 10/09/2014.
+//
+//
+
+#import
+#include "linphone/linphonecore.h"
+#include "linphone/liblinphone_tester.h"
+#import "NSObject+DTRuntime.h"
+
+@interface LinphoneTester_Tests : XCTestCase
+
+@end
+
+@implementation LinphoneTester_Tests {
+ NSString* bundlePath;
+ NSString* documentPath;
+}
+
+
+static void linphone_log_function(OrtpLogLevel lev, const char *fmt, va_list args) {
+ NSString* log = [[NSString alloc] initWithFormat:[NSString stringWithUTF8String:fmt] arguments:args];
+ NSLog(@"%@",log);
+}
+
+
+void LSLog(NSString* fmt, ...){
+ va_list args;
+ va_start(args, fmt);
+ linphone_log_function(ORTP_MESSAGE, [fmt UTF8String], args);
+ va_end(args);
+}
+
+
+
+
+- (id)init {
+ self = [super init];
+ if( self ){
+ bundlePath = [[NSBundle mainBundle] bundlePath];
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+ documentPath = [paths objectAtIndex:0];
+ LSLog(@"Bundle path: %@", bundlePath);
+ LSLog(@"Document path: %@", documentPath);
+
+ liblinphone_tester_set_fileprefix([bundlePath UTF8String]);
+ liblinphone_tester_set_writable_dir_prefix( ms_strdup([documentPath UTF8String]) );
+ }
+ return self;
+}
+
++ (NSArray*)skippedSuites {
+ NSArray* skipped_suites = @[@"Flexisip"];
+ return skipped_suites;
+}
+
++ (void)initialize {
+ liblinphone_tester_init();
+
+ int count = liblinphone_tester_nb_test_suites();
+
+ for (int i=0; i
+#import "DTObjectBlockExecutor.h"
+
+@implementation NSObject (DTRuntime)
+
+static char DTRuntimeDeallocBlocks;
+
+#pragma mark - Blocks
+
+- (void)addDeallocBlock:(void(^)())block
+{
+ // don't accept NULL block
+ NSParameterAssert(block);
+
+ NSMutableArray *deallocBlocks = objc_getAssociatedObject(self, &DTRuntimeDeallocBlocks);
+
+ // add array of dealloc blocks if not existing yet
+ if (!deallocBlocks)
+ {
+ deallocBlocks = [[NSMutableArray alloc] init];
+
+ objc_setAssociatedObject(self, &DTRuntimeDeallocBlocks, deallocBlocks, OBJC_ASSOCIATION_RETAIN);
+ }
+
+ DTObjectBlockExecutor *executor = [DTObjectBlockExecutor blockExecutorWithDeallocBlock:block];
+
+ [deallocBlocks addObject:executor];
+}
+
++ (BOOL)addInstanceMethodWithSelectorName:(NSString *)selectorName block:(void(^)(id))block
+{
+ // don't accept nil name
+ NSParameterAssert(selectorName);
+
+ // don't accept NULL block
+ NSParameterAssert(block);
+
+ // See http://stackoverflow.com/questions/6357663/casting-a-block-to-a-void-for-dynamic-class-method-resolution
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_7
+ void *impBlockForIMP = (void *)objc_unretainedPointer(block);
+#else
+ id impBlockForIMP = (__bridge id)objc_unretainedPointer(block);
+#endif
+
+ IMP myIMP = imp_implementationWithBlock(impBlockForIMP);
+
+ SEL selector = NSSelectorFromString(selectorName);
+ return class_addMethod(self, selector, myIMP, "v@:");
+}
+
+#pragma mark - Method Swizzling
+
++ (void)swizzleMethod:(SEL)selector withMethod:(SEL)otherSelector
+{
+ // my own class is being targetted
+ Class c = [self class];
+
+ // get the methods from the selectors
+ Method originalMethod = class_getInstanceMethod(c, selector);
+ Method otherMethod = class_getInstanceMethod(c, otherSelector);
+
+ if (class_addMethod(c, selector, method_getImplementation(otherMethod), method_getTypeEncoding(otherMethod)))
+ {
+ class_replaceMethod(c, otherSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
+ }
+ else
+ {
+ method_exchangeImplementations(originalMethod, otherMethod);
+ }
+}
+
++ (void)swizzleClassMethod:(SEL)selector withMethod:(SEL)otherSelector
+{
+ // my own class is being targetted
+ Class c = [self class];
+
+ // get the methods from the selectors
+ Method originalMethod = class_getClassMethod(c, selector);
+ Method otherMethod = class_getClassMethod(c, otherSelector);
+
+// if (class_addMethod(c, selector, method_getImplementation(otherMethod), method_getTypeEncoding(otherMethod)))
+// {
+// class_replaceMethod(c, otherSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
+// }
+// else
+// {
+ method_exchangeImplementations(originalMethod, otherMethod);
+// }
+
+}
+
+@end
diff --git a/LinphoneTesterTests/en.lproj/InfoPlist.strings b/LinphoneTester Tests/en.lproj/InfoPlist.strings
similarity index 100%
rename from LinphoneTesterTests/en.lproj/InfoPlist.strings
rename to LinphoneTester Tests/en.lproj/InfoPlist.strings
diff --git a/LinphoneTester/MasterViewController.m b/LinphoneTester/MasterViewController.m
index d1d0243ad..665d89832 100644
--- a/LinphoneTester/MasterViewController.m
+++ b/LinphoneTester/MasterViewController.m
@@ -47,20 +47,20 @@ static void linphone_log_function(OrtpLogLevel lev, const char *fmt, va_list arg
NSString* log = [[NSString alloc] initWithFormat:[NSString stringWithUTF8String:fmt] arguments:args];
NSLog(@"%@",log);
- [logsBuffer addObject:log];
-
- if (logsBuffer.count >= kLogsBufferCapacity ) {
- [lastLogs addObjectsFromArray:logsBuffer];
-
- if( lastLogs.count >= kLastLogsCapacity - kLogsBufferCapacity ){
- [lastLogs removeObjectsInRange:NSMakeRange(0, kLogsBufferCapacity)];
- }
- [[NSNotificationCenter defaultCenter] postNotificationName:kLogsUpdateNotification
- object:nil
- userInfo:@{@"newlogs": [logsBuffer copy]}];
- [logsBuffer removeAllObjects];
- }
-
+// [logsBuffer addObject:log];
+//
+// if (logsBuffer.count >= kLogsBufferCapacity ) {
+// [lastLogs addObjectsFromArray:logsBuffer];
+//
+// if( lastLogs.count >= kLastLogsCapacity - kLogsBufferCapacity ){
+// [lastLogs removeObjectsInRange:NSMakeRange(0, kLogsBufferCapacity)];
+// }
+// [[NSNotificationCenter defaultCenter] postNotificationName:kLogsUpdateNotification
+// object:nil
+// userInfo:@{@"newlogs": [logsBuffer copy]}];
+// [logsBuffer removeAllObjects];
+// }
+
}
diff --git a/LinphoneTester/main.m b/LinphoneTester/main.m
index ad7e760b7..4267e33f9 100644
--- a/LinphoneTester/main.m
+++ b/LinphoneTester/main.m
@@ -9,9 +9,96 @@
#import
#import "AppDelegate.h"
+#include
+#include
+
+static NSString * const kKEY_CRASH_REPORT = @"CRASH_REPORT";
+static NSString * const kKEY_ExceptionName = @"UnhandledExceptionName";
+static NSString * const kKEY_ExceptionReason = @"UnhandledExceptionReason";
+static NSString * const kKEY_ExceptionUserInfo = @"UnhandledExceptionUserInfo";
+static NSString * const kKEY_ExceptionCallStack = @"UnhandledExceptionCallStack";
+static NSString * const kKEY_ExceptionScreenshot = @"UnhandledExceptionScreenshot";
+static NSString * const kKEY_ExceptionTimestamp = @"UnhandledExceptionTimestamp";
+
+__unused void unhandledExceptionHandler(NSException *exception) {
+ NSMutableDictionary *crashReport = [NSMutableDictionary dictionary];
+ crashReport[kKEY_ExceptionName] = exception.name;
+ crashReport[kKEY_ExceptionReason] = exception.reason;
+ crashReport[kKEY_ExceptionUserInfo] = exception.userInfo ?: [NSNull null].debugDescription;
+ crashReport[kKEY_ExceptionCallStack] = exception.callStackSymbols.debugDescription;
+
+ NSLog(@"CRASH: %@ - %@", exception.name, exception.callStackSymbols.debugDescription);
+
+ [[NSUserDefaults standardUserDefaults] setObject:[NSDictionary dictionaryWithDictionary:crashReport] forKey:kKEY_CRASH_REPORT];
+ [[NSUserDefaults standardUserDefaults] synchronize];
+ exit(1);
+}
+
+/* SignalHandler
+ *
+ * Handle uncaught signals
+ */
+
+void SignalHandler(int sig, siginfo_t *info, void *context)
+{
+ void *frames[128];
+ int i,len = backtrace(frames, 128);
+ char **symbols = backtrace_symbols(frames,len);
+
+ /*
+ * Now format into a message for sending to the user
+ */
+
+ NSMutableString *buffer = [[NSMutableString alloc] initWithCapacity:4096];
+
+ NSBundle *bundle = [NSBundle mainBundle];
+ [buffer appendFormat:@"PComp version %@ build %@\n\n",
+ [bundle objectForInfoDictionaryKey:@"CFBundleVersion"],
+ [bundle objectForInfoDictionaryKey:@"CIMBuildNumber"]];
+ [buffer appendString:@"Uncaught Signal\n"];
+ [buffer appendFormat:@"si_signo %d\n",info->si_signo];
+ [buffer appendFormat:@"si_code %d\n",info->si_code];
+ [buffer appendFormat:@"si_value %d\n",info->si_value.sival_int];
+ [buffer appendFormat:@"si_errno %d\n",info->si_errno];
+ [buffer appendFormat:@"si_addr %p\n",info->si_addr];
+ [buffer appendFormat:@"si_status %d\n",info->si_status];
+ [buffer appendString:@"Stack trace:\n\n"];
+ for (i = 0; i < len; ++i) {
+ [buffer appendFormat:@"%4d - %s\n",i,symbols[i]];
+ }
+
+ /*
+ * Get the error file to write this to
+ */
+
+ NSLog(@"Error %@",buffer);
+ exit(1);
+}
+
+
+
+void InstallUncaughtExceptionHandler()
+{
+ NSSetUncaughtExceptionHandler(&unhandledExceptionHandler);
+ struct sigaction mySigAction;
+ mySigAction.sa_sigaction = SignalHandler;
+ mySigAction.sa_flags = SA_SIGINFO;
+
+ sigemptyset(&mySigAction.sa_mask);
+ sigaction(SIGQUIT, &mySigAction, NULL);
+ sigaction(SIGILL, &mySigAction, NULL);
+ sigaction(SIGTRAP, &mySigAction, NULL);
+ sigaction(SIGABRT, &mySigAction, NULL);
+ sigaction(SIGEMT, &mySigAction, NULL);
+ sigaction(SIGFPE, &mySigAction, NULL);
+ sigaction(SIGBUS, &mySigAction, NULL);
+ sigaction(SIGSEGV, &mySigAction, NULL);
+ sigaction(SIGSYS, &mySigAction, NULL);
+}
int main(int argc, char * argv[])
{
+ InstallUncaughtExceptionHandler();
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
diff --git a/LinphoneTesterTests/LinphoneTesterTests.m b/LinphoneTesterTests/LinphoneTesterTests.m
deleted file mode 100644
index 28c813448..000000000
--- a/LinphoneTesterTests/LinphoneTesterTests.m
+++ /dev/null
@@ -1,34 +0,0 @@
-//
-// LinphoneTesterTests.m
-// LinphoneTesterTests
-//
-// Created by guillaume on 28/05/2014.
-//
-//
-
-#import
-
-@interface LinphoneTesterTests : XCTestCase
-
-@end
-
-@implementation LinphoneTesterTests
-
-- (void)setUp
-{
- [super setUp];
- // Put setup code here. This method is called before the invocation of each test method in the class.
-}
-
-- (void)tearDown
-{
- // Put teardown code here. This method is called after the invocation of each test method in the class.
- [super tearDown];
-}
-
-- (void)testExample
-{
- XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__);
-}
-
-@end
diff --git a/Resources/linphonerc b/Resources/linphonerc
index 4da97f006..360d286b7 100644
--- a/Resources/linphonerc
+++ b/Resources/linphonerc
@@ -2,6 +2,8 @@
contact="Linphone iPhone"
keepalive_period=30000
default_proxy=0
+sip_port=-1
+sip_tcp_port=-1
[rtp]
audio_rtp_port=7076
@@ -21,6 +23,11 @@ firewall_policy=0
download_bw=380
upload_bw=380
+[sound]
+playback_dev_id=AU: Audio Unit Receiver
+capture_dev_id=AU: Audio Unit Receiver
+eq_active=0
+
[app]
rotation_preference=auto
animations_preference=1
@@ -29,7 +36,7 @@ use_system_contacts=0
start_at_boot_preference=1
backgroundmode_preference=1
autoanswer_notif_preference=1
-
+voiceproc_preference=1
[default_values]
reg_expires=600
\ No newline at end of file
diff --git a/Resources/linphonerc-factory b/Resources/linphonerc-factory
index 862641b0e..f9e2ab486 100644
--- a/Resources/linphonerc-factory
+++ b/Resources/linphonerc-factory
@@ -26,11 +26,11 @@ video_jitt_comp=60
nortp_timeout=30
[sound]
-playback_dev_id=AU: Audio Unit Receiver
ringer_dev_id=AQ: Audio Queue Device
-capture_dev_id=AU: Audio Unit Receiver
echocancellation=0
dtmf_player_amp=0.007
+eq_location=mic
+eq_gains=50:2:50 100:2:50
[misc]
history_max_size=30
@@ -42,7 +42,7 @@ domain=sip.linphone.org
proxy=sip.linphone.org:5223
password_length=6
username_length=4
-expires=604800
+expires=1314000
push_notification=1
transport=tls
sharing_server=https://www.linphone.org:444/upload.php
diff --git a/Resources/linphonerc-factory~ipad b/Resources/linphonerc-factory~ipad
index 7f828cd26..b34cdc13d 100644
--- a/Resources/linphonerc-factory~ipad
+++ b/Resources/linphonerc-factory~ipad
@@ -26,11 +26,11 @@ video_jitt_comp=60
nortp_timeout=30
[sound]
-playback_dev_id=AU: Audio Unit Receiver
ringer_dev_id=AQ: Audio Queue Device
-capture_dev_id=AU: Audio Unit Receiver
echocancellation=0
dtmf_player_amp=0.007
+eq_location=mic
+eq_gains=50:2:50 100:2:50
[misc]
history_max_size=30
@@ -42,7 +42,7 @@ domain=sip.linphone.org
proxy=sip.linphone.org:5223
password_length=6
username_length=4
-expires=604800
+expires=1314000
push_notification=1
transport=tls
sharing_server=https://www.linphone.org:444/upload.php
diff --git a/Resources/linphonerc~ipad b/Resources/linphonerc~ipad
index 008d4a702..2f010650c 100644
--- a/Resources/linphonerc~ipad
+++ b/Resources/linphonerc~ipad
@@ -2,6 +2,8 @@
contact="Linphone iPhone"
keepalive_period=30000
default_proxy=0
+sip_port=-1
+sip_tcp_port=-1
[rtp]
audio_rtp_port=7076
@@ -21,6 +23,11 @@ firewall_policy=0
download_bw=512
upload_bw=512
+[sound]
+playback_dev_id=AU: Audio Unit Receiver
+capture_dev_id=AU: Audio Unit Receiver
+eq_active=0
+
[app]
rotation_preference=auto
animations_preference=1
@@ -29,6 +36,7 @@ use_system_contacts=0
start_at_boot_preference=1
backgroundmode_preference=1
autoanswer_notif_preference=1
+voiceproc_preference=1
[default_values]
reg_expires=600
diff --git a/Resources/wizard_linphone_create.rc b/Resources/wizard_linphone_create.rc
index 75946fd57..292d662d4 100644
--- a/Resources/wizard_linphone_create.rc
+++ b/Resources/wizard_linphone_create.rc
@@ -5,7 +5,7 @@
<sip:sip.linphone.org:5223;transport=tls>
<sip:sip.linphone.org:5223;transport=tls>
sip:?@sip.linphone.org
- 604800
+ 1314000
1
0
0
diff --git a/Resources/wizard_linphone_existing.rc b/Resources/wizard_linphone_existing.rc
index 2b2d950e9..2244776e8 100644
--- a/Resources/wizard_linphone_existing.rc
+++ b/Resources/wizard_linphone_existing.rc
@@ -5,7 +5,7 @@
<sip:sip.linphone.org:5223;transport=tls>
<sip:sip.linphone.org:5223;transport=tls>
sip:?@sip.linphone.org
- 604800
+ 1314000
1
0
0
diff --git a/Settings/InAppSettings.bundle/Audio.plist b/Settings/InAppSettings.bundle/Audio.plist
index ac3e769a2..1121dd229 100644
--- a/Settings/InAppSettings.bundle/Audio.plist
+++ b/Settings/InAppSettings.bundle/Audio.plist
@@ -198,6 +198,26 @@
Type
PSToggleSwitchSpecifier
+
+ DefaultValue
+ Simple
+ Key
+ adaptive_rate_algorithm_preference
+ Title
+ Adaptive rate algorithm
+ Titles
+
+ Simple
+ Stateful
+
+ Type
+ PSMultiValueSpecifier
+ Values
+
+ Simple
+ Stateful
+
+
DefaultValue
36
@@ -226,6 +246,26 @@
128
+
+ DefaultValue
+
+ Key
+ voiceproc_preference
+ Title
+ Enable Voice Processing
+ Type
+ PSToggleSwitchSpecifier
+
+
+ DefaultValue
+
+ Key
+ eq_active
+ Title
+ Enable Bass Boost
+ Type
+ PSToggleSwitchSpecifier
+
diff --git a/Settings/InAppSettings.bundle/Call.plist b/Settings/InAppSettings.bundle/Call.plist
index 545bb198d..3b2503bfd 100644
--- a/Settings/InAppSettings.bundle/Call.plist
+++ b/Settings/InAppSettings.bundle/Call.plist
@@ -88,6 +88,24 @@
IASKTextAlignment
IASKUITextAlignmentRight
+
+ Key
+ voice_mail_uri_preference
+ Title
+ Voice mail URI
+ AutocapitalizationType
+ None
+ AutocorrectionType
+ No
+ DefaultValue
+
+ IsSecure
+
+ Type
+ PSTextFieldSpecifier
+ IASKTextAlignment
+ IASKUITextAlignmentRight
+
diff --git a/Settings/InAppSettings.bundle/en.lproj/Audio.strings b/Settings/InAppSettings.bundle/en.lproj/Audio.strings
index 4384de768..db5389c2a 100644
--- a/Settings/InAppSettings.bundle/en.lproj/Audio.strings
+++ b/Settings/InAppSettings.bundle/en.lproj/Audio.strings
@@ -48,3 +48,9 @@
/* Codec bitrate limit */
"Codec bitrate limit" = "Codec bitrate limit";
+
+/* Voice processing */
+"Enable Voice Processing"="Enable Voice Processing";
+
+/* Bass Boost / equalizer */
+"Enable Bass Boost"="Enable Bass Boost";
\ No newline at end of file
diff --git a/Settings/InAppSettings.bundle/fr.lproj/Audio.strings b/Settings/InAppSettings.bundle/fr.lproj/Audio.strings
index c90dc9783..5295f9cc3 100644
--- a/Settings/InAppSettings.bundle/fr.lproj/Audio.strings
+++ b/Settings/InAppSettings.bundle/fr.lproj/Audio.strings
@@ -48,3 +48,16 @@
/* Codec bitrate limit */
"Codec bitrate limit" = "Limite de débit du codec";
+
+/* Voice processing */
+"Enable Voice Processing"="Optimiser le son pour la VoIP";
+
+/* Bass Boost / equalizer */
+"Enable Bass Boost"="Activer Bass Boost";
+
+/* Adaptative */
+"Adaptive rate algorithm"="Adaptation du débit";
+
+"Simple"="Simple";
+
+"Stateful"="Stateful";
\ No newline at end of file
diff --git a/Settings/InAppSettings.bundle/ru.lproj/Audio.strings b/Settings/InAppSettings.bundle/ru.lproj/Audio.strings
index 2b325e3ae..05456dfcd 100644
--- a/Settings/InAppSettings.bundle/ru.lproj/Audio.strings
+++ b/Settings/InAppSettings.bundle/ru.lproj/Audio.strings
@@ -48,3 +48,9 @@
/* Codec bitrate limit */
"Codec bitrate limit" = "Codec bitrate limit";
+
+/* Voice processing */
+"Enable Voice Processing"="Enable Voice Processing";
+
+/* Bass Boost / equalizer */
+"Enable Bass Boost"="Enable Bass Boost";
\ No newline at end of file
diff --git a/UI.md b/UI.md
new file mode 100644
index 000000000..e048dafdc
--- /dev/null
+++ b/UI.md
@@ -0,0 +1,34 @@
+
+Quick UI reference for Linphone iOS:
+
+- The app is contained in a window, which resides in the MainStoryboard file.
+- The delegate is set to LinphoneAppDelegate in main.m, in the UIApplicationMain() by passing its class
+- Basic layout:
+
+
+MainStoryboard
+ |
+ | (rootViewController)
+ |
+ PhoneMainView ---> view #--> app background
+ | |
+ | #--> statusbar background
+ |
+ | (mainViewController)
+ |
+ UICompositeViewController : TPMultilayout
+ |
+ #---> view #--> stateBar
+ |
+ #--> contentView
+ |
+ #--> tabBar
+
+
+When the app is started, the phoneMainView gets asked to transition to the Dialer view or the Wizard view.
+PhoneMainView exposes the -changeCurrentView: method, which will setup its
+Any Linphone view is actually presented in the UICompositeViewController, with or without a stateBar and tabBar.
+
+The UICompositeViewController consists of 3 areas laid out vertically. From top to bottom: StateBar, Content and TabBar.
+The TabBar is usually the UIMainBar, which is used as a navigation controller: clicking on each of the buttons will trigger
+a transition to another "view".
\ No newline at end of file
diff --git a/linphone-Info.plist b/linphone-Info.plist
index 1fa197020..2f7284c5b 100644
--- a/linphone-Info.plist
+++ b/linphone-Info.plist
@@ -59,7 +59,7 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 3.7.2
+ 3.7.3
CFBundleURLTypes
@@ -100,11 +100,9 @@
CFBundleVersion
- 2.2.2
- NSMainNibFile
- LinphoneApp
- NSMainNibFile~ipad
- LinphoneApp
+ 2.2.3
+ LSRequiresIPhoneOS
+
UIApplicationExitsOnSuspend
UIBackgroundModes
@@ -117,6 +115,8 @@
linphone_splashscreen
UILaunchImageFile~iphone
linphone_splashscreen
+ UIMainStoryboardFile
+ MainStoryboard
UIRequiredDeviceCapabilities
wifi
diff --git a/linphone.xcodeproj/project.pbxproj b/linphone.xcodeproj/project.pbxproj
index 17ccb5ea7..ec75b5504 100755
--- a/linphone.xcodeproj/project.pbxproj
+++ b/linphone.xcodeproj/project.pbxproj
@@ -203,6 +203,10 @@
57F005C915EE2D9200914747 /* linphonerc-factory in Resources */ = {isa = PBXBuildFile; fileRef = 57F005C615EE2D9200914747 /* linphonerc-factory */; };
57F005CA15EE2D9200914747 /* linphonerc-factory~ipad in Resources */ = {isa = PBXBuildFile; fileRef = 57F005C715EE2D9200914747 /* linphonerc-factory~ipad */; };
57F005CB15EE2D9200914747 /* linphonerc-factory~ipad in Resources */ = {isa = PBXBuildFile; fileRef = 57F005C715EE2D9200914747 /* linphonerc-factory~ipad */; };
+ 631C4FB119D2A8F2004BFE77 /* UIDigitButtonLongPlus.m in Sources */ = {isa = PBXBuildFile; fileRef = 631C4FB019D2A8F2004BFE77 /* UIDigitButtonLongPlus.m */; };
+ 631C4FB219D2A8F2004BFE77 /* UIDigitButtonLongPlus.m in Sources */ = {isa = PBXBuildFile; fileRef = 631C4FB019D2A8F2004BFE77 /* UIDigitButtonLongPlus.m */; };
+ 631C4FB719D2C3A6004BFE77 /* UIDigitButtonLongVoiceMail.m in Sources */ = {isa = PBXBuildFile; fileRef = 631C4FB619D2C3A6004BFE77 /* UIDigitButtonLongVoiceMail.m */; };
+ 631C4FB819D2C3A6004BFE77 /* UIDigitButtonLongVoiceMail.m in Sources */ = {isa = PBXBuildFile; fileRef = 631C4FB619D2C3A6004BFE77 /* UIDigitButtonLongVoiceMail.m */; };
70571E1A13FABCB000CDD3C2 /* rootca.pem in Resources */ = {isa = PBXBuildFile; fileRef = 70571E1913FABCB000CDD3C2 /* rootca.pem */; };
7066FC0C13E830E400EFC6DC /* libvpx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7066FC0B13E830E400EFC6DC /* libvpx.a */; };
70E542F313E147E3002BA2C0 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70E542F213E147E3002BA2C0 /* OpenGLES.framework */; };
@@ -1349,12 +1353,23 @@
F04892FF180C3296002FED35 /* ImageOptim.sh in Resources */ = {isa = PBXBuildFile; fileRef = F04892FE180C3296002FED35 /* ImageOptim.sh */; };
F0489300180C3296002FED35 /* ImageOptim.sh in Resources */ = {isa = PBXBuildFile; fileRef = F04892FE180C3296002FED35 /* ImageOptim.sh */; };
F04F1E9D1806A41800D080F2 /* libpolarssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 57B0E35F173C010400A476B8 /* libpolarssl.a */; };
+ F0642EF119DAC891009DB336 /* MainStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F0642EF019DAC891009DB336 /* MainStoryboard.storyboard */; };
+ F0642EF219DAC891009DB336 /* MainStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F0642EF019DAC891009DB336 /* MainStoryboard.storyboard */; };
F066515517F9A02E0064280C /* UITransparentTVCell.m in Sources */ = {isa = PBXBuildFile; fileRef = F066515417F9A02E0064280C /* UITransparentTVCell.m */; };
F066515617F9A02E0064280C /* UITransparentTVCell.m in Sources */ = {isa = PBXBuildFile; fileRef = F066515417F9A02E0064280C /* UITransparentTVCell.m */; };
F0818E7E17FC51D8005A3330 /* linphone_icon_76.png in Resources */ = {isa = PBXBuildFile; fileRef = F0818E7C17FC51D8005A3330 /* linphone_icon_76.png */; };
F0818E7F17FC51D8005A3330 /* linphone_icon_76.png in Resources */ = {isa = PBXBuildFile; fileRef = F0818E7C17FC51D8005A3330 /* linphone_icon_76.png */; };
F0818E8017FC51D8005A3330 /* linphone_icon_152.png in Resources */ = {isa = PBXBuildFile; fileRef = F0818E7D17FC51D8005A3330 /* linphone_icon_152.png */; };
F0818E8117FC51D8005A3330 /* linphone_icon_152.png in Resources */ = {isa = PBXBuildFile; fileRef = F0818E7D17FC51D8005A3330 /* linphone_icon_152.png */; };
+ F08F118519C09C6B007D70C2 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A9B3318C0CF7000C4D7FE /* XCTest.framework */; };
+ F08F118619C09C6B007D70C2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
+ F08F118719C09C6B007D70C2 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };
+ F08F118D19C09C6B007D70C2 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = F08F118B19C09C6B007D70C2 /* InfoPlist.strings */; };
+ F08F118F19C09C6B007D70C2 /* LinphoneTester_Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = F08F118E19C09C6B007D70C2 /* LinphoneTester_Tests.m */; };
+ F08F119919C09D88007D70C2 /* flexisip in Resources */ = {isa = PBXBuildFile; fileRef = F08F119819C09D88007D70C2 /* flexisip */; };
+ F08F119A19C09D88007D70C2 /* flexisip in Resources */ = {isa = PBXBuildFile; fileRef = F08F119819C09D88007D70C2 /* flexisip */; };
+ F08F119D19C0A65B007D70C2 /* NSObject+DTRuntime.m in Sources */ = {isa = PBXBuildFile; fileRef = F08F119C19C0A65B007D70C2 /* NSObject+DTRuntime.m */; };
+ F08F11A019C0A6CB007D70C2 /* DTObjectBlockExecutor.m in Sources */ = {isa = PBXBuildFile; fileRef = F08F119F19C0A6CB007D70C2 /* DTObjectBlockExecutor.m */; };
F0938159188E629800A55DFA /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = F0938158188E629800A55DFA /* iTunesArtwork */; };
F093815A188E629800A55DFA /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = F0938158188E629800A55DFA /* iTunesArtwork */; };
F0A2759C18157A6000B6D61A /* linphone_icon_120.png in Resources */ = {isa = PBXBuildFile; fileRef = F0818E7B17FC5160005A3330 /* linphone_icon_120.png */; };
@@ -1417,11 +1432,9 @@
F0BB8C3C19362C2200974404 /* certificates in Resources */ = {isa = PBXBuildFile; fileRef = F0BB8C3919362C2200974404 /* certificates */; };
F0BB8C3D19362C2200974404 /* images in Resources */ = {isa = PBXBuildFile; fileRef = F0BB8C3A19362C2200974404 /* images */; };
F0BB8C3E19362C2200974404 /* sounds in Resources */ = {isa = PBXBuildFile; fileRef = F0BB8C3B19362C2200974404 /* sounds */; };
- F0BB8C44193630CA00974404 /* flexisip.conf in Resources */ = {isa = PBXBuildFile; fileRef = F0BB8C3F193630CA00974404 /* flexisip.conf */; };
F0BB8C45193630CA00974404 /* local_tester_hosts in Resources */ = {isa = PBXBuildFile; fileRef = F0BB8C40193630CA00974404 /* local_tester_hosts */; };
F0BB8C46193630CA00974404 /* marie_xml in Resources */ = {isa = PBXBuildFile; fileRef = F0BB8C41193630CA00974404 /* marie_xml */; };
F0BB8C47193630CA00974404 /* tester_hosts in Resources */ = {isa = PBXBuildFile; fileRef = F0BB8C42193630CA00974404 /* tester_hosts */; };
- F0BB8C48193630CA00974404 /* userdb.conf in Resources */ = {isa = PBXBuildFile; fileRef = F0BB8C43193630CA00974404 /* userdb.conf */; };
F0BB8C4C193631D200974404 /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 22276E8813C73DC000210156 /* CoreMedia.framework */; };
F0BB8C4D193631DF00974404 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 224567C1107B968500F10948 /* AVFoundation.framework */; };
F476004B147AAF2800FFF19B /* liblinphone.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2211DB911475562600DEE054 /* liblinphone.a */; };
@@ -1474,6 +1487,13 @@
remoteGlobalIDString = D2AAC07D0554694100DB518D;
remoteInfo = NinePatch;
};
+ F08F119119C09C6B007D70C2 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = F0BB8BD41936208100974404;
+ remoteInfo = LinphoneTester;
+ };
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
@@ -1631,6 +1651,10 @@
57F005C315EE2CCF00914747 /* linphonerc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = linphonerc; path = Resources/linphonerc; sourceTree = ""; };
57F005C615EE2D9200914747 /* linphonerc-factory */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = "linphonerc-factory"; path = "Resources/linphonerc-factory"; sourceTree = ""; };
57F005C715EE2D9200914747 /* linphonerc-factory~ipad */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = "linphonerc-factory~ipad"; path = "Resources/linphonerc-factory~ipad"; sourceTree = ""; };
+ 631C4FAF19D2A8F2004BFE77 /* UIDigitButtonLongPlus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIDigitButtonLongPlus.h; sourceTree = ""; };
+ 631C4FB019D2A8F2004BFE77 /* UIDigitButtonLongPlus.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIDigitButtonLongPlus.m; sourceTree = ""; };
+ 631C4FB519D2C3A6004BFE77 /* UIDigitButtonLongVoiceMail.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIDigitButtonLongVoiceMail.h; sourceTree = ""; };
+ 631C4FB619D2C3A6004BFE77 /* UIDigitButtonLongVoiceMail.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIDigitButtonLongVoiceMail.m; sourceTree = ""; };
70571E1913FABCB000CDD3C2 /* rootca.pem */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = rootca.pem; path = "liblinphone-sdk/apple-darwin/share/linphone/rootca.pem"; sourceTree = ""; };
7066FC0B13E830E400EFC6DC /* libvpx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvpx.a; path = "liblinphone-sdk/apple-darwin/lib/libvpx.a"; sourceTree = ""; };
70E542F213E147E3002BA2C0 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
@@ -2260,11 +2284,23 @@
F03CA84118C72F1A0008889D /* UITextViewNoDefine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UITextViewNoDefine.h; sourceTree = ""; };
F03CA84218C72F1A0008889D /* UITextViewNoDefine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UITextViewNoDefine.m; sourceTree = ""; };
F04892FE180C3296002FED35 /* ImageOptim.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = ImageOptim.sh; sourceTree = ""; };
+ F0642EF019DAC891009DB336 /* MainStoryboard.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = MainStoryboard.storyboard; sourceTree = ""; };
+ F0642EF719DAF32E009DB336 /* DTWeakSupport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DTWeakSupport.h; sourceTree = ""; };
F066515317F9A02E0064280C /* UITransparentTVCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UITransparentTVCell.h; sourceTree = ""; };
F066515417F9A02E0064280C /* UITransparentTVCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UITransparentTVCell.m; sourceTree = ""; };
F0818E7B17FC5160005A3330 /* linphone_icon_120.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = linphone_icon_120.png; path = Resources/linphone_icon_120.png; sourceTree = ""; };
F0818E7C17FC51D8005A3330 /* linphone_icon_76.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = linphone_icon_76.png; path = Resources/linphone_icon_76.png; sourceTree = ""; };
F0818E7D17FC51D8005A3330 /* linphone_icon_152.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = linphone_icon_152.png; path = Resources/linphone_icon_152.png; sourceTree = ""; };
+ F08F118419C09C6A007D70C2 /* LinphoneTester Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "LinphoneTester Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
+ F08F118A19C09C6B007D70C2 /* LinphoneTester Tests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "LinphoneTester Tests-Info.plist"; sourceTree = ""; };
+ F08F118C19C09C6B007D70C2 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
+ F08F118E19C09C6B007D70C2 /* LinphoneTester_Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LinphoneTester_Tests.m; sourceTree = ""; };
+ F08F119019C09C6B007D70C2 /* LinphoneTester Tests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "LinphoneTester Tests-Prefix.pch"; sourceTree = ""; };
+ F08F119819C09D88007D70C2 /* flexisip */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flexisip; path = submodules/linphone/tester/flexisip; sourceTree = SOURCE_ROOT; };
+ F08F119B19C0A65A007D70C2 /* NSObject+DTRuntime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+DTRuntime.h"; sourceTree = ""; };
+ F08F119C19C0A65B007D70C2 /* NSObject+DTRuntime.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+DTRuntime.m"; sourceTree = ""; };
+ F08F119E19C0A6CB007D70C2 /* DTObjectBlockExecutor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTObjectBlockExecutor.h; sourceTree = ""; };
+ F08F119F19C0A6CB007D70C2 /* DTObjectBlockExecutor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTObjectBlockExecutor.m; sourceTree = ""; };
F0938158188E629800A55DFA /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTunesArtwork; sourceTree = ""; };
F09548181883F15300E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ChatRoomViewController.xib; sourceTree = ""; };
F09548191883F15300E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ChatViewController.xib; sourceTree = ""; };
@@ -2356,9 +2392,6 @@
F0BB8BEE1936208200974404 /* DetailViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DetailViewController.h; sourceTree = ""; };
F0BB8BEF1936208200974404 /* DetailViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DetailViewController.m; sourceTree = ""; };
F0BB8BF11936208200974404 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
- F0BB8BFF1936208200974404 /* LinphoneTesterTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "LinphoneTesterTests-Info.plist"; sourceTree = ""; };
- F0BB8C011936208200974404 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
- F0BB8C031936208200974404 /* LinphoneTesterTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LinphoneTesterTests.m; sourceTree = ""; };
F0BB8C0F193623F200974404 /* liblinphonetester.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblinphonetester.a; path = "liblinphone-sdk/apple-darwin/lib/liblinphonetester.a"; sourceTree = ""; };
F0BB8C111936240300974404 /* libcunit.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcunit.a; path = "liblinphone-sdk/apple-darwin/lib/libcunit.a"; sourceTree = ""; };
F0BB8C311936246600974404 /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; };
@@ -2367,11 +2400,9 @@
F0BB8C3919362C2200974404 /* certificates */ = {isa = PBXFileReference; lastKnownFileType = folder; name = certificates; path = submodules/linphone/tester/certificates; sourceTree = SOURCE_ROOT; };
F0BB8C3A19362C2200974404 /* images */ = {isa = PBXFileReference; lastKnownFileType = folder; name = images; path = submodules/linphone/tester/images; sourceTree = SOURCE_ROOT; };
F0BB8C3B19362C2200974404 /* sounds */ = {isa = PBXFileReference; lastKnownFileType = folder; name = sounds; path = submodules/linphone/tester/sounds; sourceTree = SOURCE_ROOT; };
- F0BB8C3F193630CA00974404 /* flexisip.conf */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = flexisip.conf; path = submodules/linphone/tester/flexisip.conf; sourceTree = SOURCE_ROOT; };
F0BB8C40193630CA00974404 /* local_tester_hosts */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = local_tester_hosts; path = submodules/linphone/tester/local_tester_hosts; sourceTree = SOURCE_ROOT; };
F0BB8C41193630CA00974404 /* marie_xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = marie_xml; path = submodules/linphone/tester/marie_xml; sourceTree = SOURCE_ROOT; };
F0BB8C42193630CA00974404 /* tester_hosts */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = tester_hosts; path = submodules/linphone/tester/tester_hosts; sourceTree = SOURCE_ROOT; };
- F0BB8C43193630CA00974404 /* userdb.conf */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = userdb.conf; path = submodules/linphone/tester/userdb.conf; sourceTree = SOURCE_ROOT; };
F0BB8C4A193631B300974404 /* ImageIO.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ImageIO.framework; path = System/Library/Frameworks/ImageIO.framework; sourceTree = SDKROOT; };
F84015BC1939FE37006ABAB5 /* test_failed.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = test_failed.png; path = Resources/test_failed.png; sourceTree = ""; };
F84015BD1939FE37006ABAB5 /* test_inprogress.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = test_inprogress.png; path = Resources/test_inprogress.png; sourceTree = ""; };
@@ -2498,6 +2529,16 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ F08F118119C09C6A007D70C2 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F08F118519C09C6B007D70C2 /* XCTest.framework in Frameworks */,
+ F08F118719C09C6B007D70C2 /* UIKit.framework in Frameworks */,
+ F08F118619C09C6B007D70C2 /* Foundation.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
F0BB8BD21936208100974404 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@@ -2633,6 +2674,7 @@
D38187E015FE348A00C3EDCA /* WizardViewController.xib */,
D3D5126E160B3AD400946DF8 /* WizardViewController~ipad.xib */,
D3D5126A160B3A8E00946DF8 /* WizardViews.xib */,
+ F0642EF019DAC891009DB336 /* MainStoryboard.storyboard */,
);
path = Classes;
sourceTree = "";
@@ -2643,6 +2685,7 @@
1D6058910D05DD3D006BFB54 /* linphone.app */,
22D8F187147548E2008C97DB /* linphone-no-gpl-thirdparties.app */,
F0BB8BD51936208100974404 /* LinphoneTester.app */,
+ F08F118419C09C6A007D70C2 /* LinphoneTester Tests.xctest */,
);
name = Products;
sourceTree = "";
@@ -2688,6 +2731,10 @@
D381881815FE3F7F00C3EDCA /* UIContactDetailsHeader.xib */,
2248E90C12F7E4CF00220D9C /* UIDigitButton.h */,
2248E90D12F7E4CF00220D9C /* UIDigitButton.m */,
+ 631C4FAF19D2A8F2004BFE77 /* UIDigitButtonLongPlus.h */,
+ 631C4FB019D2A8F2004BFE77 /* UIDigitButtonLongPlus.m */,
+ 631C4FB519D2C3A6004BFE77 /* UIDigitButtonLongVoiceMail.h */,
+ 631C4FB619D2C3A6004BFE77 /* UIDigitButtonLongVoiceMail.m */,
D3C6526515AC1A8F0092A874 /* UIEditableTableViewCell.h */,
D3C6526615AC1A8F0092A874 /* UIEditableTableViewCell.m */,
22BB1A67132FF16A005CD7AA /* UIEraseButton.h */,
@@ -2720,18 +2767,18 @@
D354981E1587716B000081D8 /* UIStateBar.h */,
D354981F1587716B000081D8 /* UIStateBar.m */,
D35498201587716B000081D8 /* UIStateBar.xib */,
+ F03CA84118C72F1A0008889D /* UITextViewNoDefine.h */,
+ F03CA84218C72F1A0008889D /* UITextViewNoDefine.m */,
D32648421588F6FA00930C67 /* UIToggleButton.h */,
D32648431588F6FB00930C67 /* UIToggleButton.m */,
D3196D3C15A32BD7007FEEBA /* UITransferButton.h */,
D3196D3D15A32BD8007FEEBA /* UITransferButton.m */,
+ F066515317F9A02E0064280C /* UITransparentTVCell.h */,
+ F066515417F9A02E0064280C /* UITransparentTVCell.m */,
D32460E4159D9AAD00BA7F3A /* UITransparentView.h */,
D32460E5159D9AAD00BA7F3A /* UITransparentView.m */,
340751E5150F38FC00B89C47 /* UIVideoButton.h */,
340751E6150F38FD00B89C47 /* UIVideoButton.m */,
- F066515317F9A02E0064280C /* UITransparentTVCell.h */,
- F066515417F9A02E0064280C /* UITransparentTVCell.m */,
- F03CA84118C72F1A0008889D /* UITextViewNoDefine.h */,
- F03CA84218C72F1A0008889D /* UITextViewNoDefine.m */,
);
path = LinphoneUI;
sourceTree = "";
@@ -2739,15 +2786,15 @@
29B97314FDCFA39411CA2CEA /* CustomTemplate */ = {
isa = PBXGroup;
children = (
- F0938158188E629800A55DFA /* iTunesArtwork */,
- 2258633C11410BAC00C5A737 /* README */,
- F04892FE180C3296002FED35 /* ImageOptim.sh */,
080E96DDFE201D6D7F000001 /* Classes */,
29B97323FDCFA39411CA2CEA /* Frameworks */,
+ F04892FE180C3296002FED35 /* ImageOptim.sh */,
+ F0938158188E629800A55DFA /* iTunesArtwork */,
F0BB8BD91936208100974404 /* LinphoneTester */,
- F0BB8BFD1936208200974404 /* LinphoneTesterTests */,
+ F08F118819C09C6B007D70C2 /* LinphoneTester Tests */,
29B97315FDCFA39411CA2CEA /* Other Sources */,
19C28FACFE9D520D11CA2CBB /* Products */,
+ 2258633C11410BAC00C5A737 /* README */,
29B97317FDCFA39411CA2CEA /* Resources */,
D398D3031594B0FB00FD553C /* Settings */,
);
@@ -2910,6 +2957,7 @@
children = (
D37EE160160377D7003608A6 /* DTActionSheet.h */,
D37EE161160377D7003608A6 /* DTActionSheet.m */,
+ F0642EF719DAF32E009DB336 /* DTWeakSupport.h */,
);
name = DTFoundation;
path = Utils/DTFoundation;
@@ -3038,6 +3086,29 @@
name = UACellBackgroundView;
sourceTree = "";
};
+ F08F118819C09C6B007D70C2 /* LinphoneTester Tests */ = {
+ isa = PBXGroup;
+ children = (
+ F08F118E19C09C6B007D70C2 /* LinphoneTester_Tests.m */,
+ F08F119E19C0A6CB007D70C2 /* DTObjectBlockExecutor.h */,
+ F08F119F19C0A6CB007D70C2 /* DTObjectBlockExecutor.m */,
+ F08F119B19C0A65A007D70C2 /* NSObject+DTRuntime.h */,
+ F08F119C19C0A65B007D70C2 /* NSObject+DTRuntime.m */,
+ F08F118919C09C6B007D70C2 /* Supporting Files */,
+ );
+ path = "LinphoneTester Tests";
+ sourceTree = "";
+ };
+ F08F118919C09C6B007D70C2 /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ F08F118A19C09C6B007D70C2 /* LinphoneTester Tests-Info.plist */,
+ F08F118B19C09C6B007D70C2 /* InfoPlist.strings */,
+ F08F119019C09C6B007D70C2 /* LinphoneTester Tests-Prefix.pch */,
+ );
+ name = "Supporting Files";
+ sourceTree = "";
+ };
F0B89C2318DC90850050B60E /* images */ = {
isa = PBXGroup;
children = (
@@ -3555,11 +3626,10 @@
F0BB8BDA1936208100974404 /* Supporting Files */ = {
isa = PBXGroup;
children = (
- F0BB8C3F193630CA00974404 /* flexisip.conf */,
+ F08F119819C09D88007D70C2 /* flexisip */,
F0BB8C40193630CA00974404 /* local_tester_hosts */,
F0BB8C41193630CA00974404 /* marie_xml */,
F0BB8C42193630CA00974404 /* tester_hosts */,
- F0BB8C43193630CA00974404 /* userdb.conf */,
F0BB8C3919362C2200974404 /* certificates */,
F0BB8C3A19362C2200974404 /* images */,
F0BB8C3B19362C2200974404 /* sounds */,
@@ -3572,24 +3642,6 @@
name = "Supporting Files";
sourceTree = "";
};
- F0BB8BFD1936208200974404 /* LinphoneTesterTests */ = {
- isa = PBXGroup;
- children = (
- F0BB8C031936208200974404 /* LinphoneTesterTests.m */,
- F0BB8BFE1936208200974404 /* Supporting Files */,
- );
- path = LinphoneTesterTests;
- sourceTree = "";
- };
- F0BB8BFE1936208200974404 /* Supporting Files */ = {
- isa = PBXGroup;
- children = (
- F0BB8BFF1936208200974404 /* LinphoneTesterTests-Info.plist */,
- F0BB8C001936208200974404 /* InfoPlist.strings */,
- );
- name = "Supporting Files";
- sourceTree = "";
- };
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -3635,6 +3687,24 @@
productReference = 22D8F187147548E2008C97DB /* linphone-no-gpl-thirdparties.app */;
productType = "com.apple.product-type.application";
};
+ F08F118319C09C6A007D70C2 /* LinphoneTester Tests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = F08F119319C09C6B007D70C2 /* Build configuration list for PBXNativeTarget "LinphoneTester Tests" */;
+ buildPhases = (
+ F08F118019C09C6A007D70C2 /* Sources */,
+ F08F118119C09C6A007D70C2 /* Frameworks */,
+ F08F118219C09C6A007D70C2 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ F08F119219C09C6B007D70C2 /* PBXTargetDependency */,
+ );
+ name = "LinphoneTester Tests";
+ productName = "LinphoneTester Tests";
+ productReference = F08F118419C09C6A007D70C2 /* LinphoneTester Tests.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
F0BB8BD41936208100974404 /* LinphoneTester */ = {
isa = PBXNativeTarget;
buildConfigurationList = F0BB8C051936208200974404 /* Build configuration list for PBXNativeTarget "LinphoneTester" */;
@@ -3642,6 +3712,7 @@
F0BB8BD11936208100974404 /* Sources */,
F0BB8BD21936208100974404 /* Frameworks */,
F0BB8BD31936208100974404 /* Resources */,
+ F08F11A219C0AC2F007D70C2 /* ShellScript */,
);
buildRules = (
);
@@ -3666,6 +3737,10 @@
22D8F11D147548E2008C97DB = {
DevelopmentTeam = Z2V957B3D6;
};
+ F08F118319C09C6A007D70C2 = {
+ DevelopmentTeam = Z2V957B3D6;
+ TestTargetID = F0BB8BD41936208100974404;
+ };
F0BB8BD41936208100974404 = {
DevelopmentTeam = Z2V957B3D6;
};
@@ -3702,6 +3777,7 @@
1D6058900D05DD3D006BFB54 /* linphone */,
22D8F11D147548E2008C97DB /* linphone-no-gpl-thirdparties */,
F0BB8BD41936208100974404 /* LinphoneTester */,
+ F08F118319C09C6A007D70C2 /* LinphoneTester Tests */,
);
};
/* End PBXProject section */
@@ -4094,6 +4170,7 @@
D3A74F4215C69392001500B9 /* speaker_on_disabled~ipad.png in Resources */,
D3A74F4415C69392001500B9 /* speaker_on_over~ipad.png in Resources */,
D3A74F4615C69392001500B9 /* statebar_background_landscape~ipad.png in Resources */,
+ F0642EF119DAC891009DB336 /* MainStoryboard.storyboard in Resources */,
D3A74F4815C69392001500B9 /* statebar_background~ipad.png in Resources */,
D3A74F4A15C69392001500B9 /* transfer_call_default~ipad.png in Resources */,
D3A74F4C15C69392001500B9 /* transfer_call_over~ipad.png in Resources */,
@@ -4640,6 +4717,7 @@
D3A74F4315C69392001500B9 /* speaker_on_disabled~ipad.png in Resources */,
D3A74F4515C69392001500B9 /* speaker_on_over~ipad.png in Resources */,
D3A74F4715C69392001500B9 /* statebar_background_landscape~ipad.png in Resources */,
+ F0642EF219DAC891009DB336 /* MainStoryboard.storyboard in Resources */,
D3A74F4915C69392001500B9 /* statebar_background~ipad.png in Resources */,
D3A74F4B15C69392001500B9 /* transfer_call_default~ipad.png in Resources */,
D3A74F4D15C69392001500B9 /* transfer_call_over~ipad.png in Resources */,
@@ -4816,16 +4894,24 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ F08F118219C09C6A007D70C2 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F08F119A19C09D88007D70C2 /* flexisip in Resources */,
+ F08F118D19C09C6B007D70C2 /* InfoPlist.strings in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
F0BB8BD31936208100974404 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F0BB8C3819362C1500974404 /* rcfiles in Resources */,
F84015C11939FE37006ABAB5 /* test_passed.png in Resources */,
- F0BB8C44193630CA00974404 /* flexisip.conf in Resources */,
+ F08F119919C09D88007D70C2 /* flexisip in Resources */,
F0BB8C46193630CA00974404 /* marie_xml in Resources */,
F0BB8BEA1936208200974404 /* Main_iPad.storyboard in Resources */,
- F0BB8C48193630CA00974404 /* userdb.conf in Resources */,
F0BB8C3E19362C2200974404 /* sounds in Resources */,
F84015BF1939FE37006ABAB5 /* test_failed.png in Resources */,
F0BB8BF21936208200974404 /* Images.xcassets in Resources */,
@@ -4868,6 +4954,19 @@
shellPath = /bin/sh;
shellScript = $SRCROOT/ImageOptim.sh;
};
+ F08F11A219C0AC2F007D70C2 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 12;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "if [ \"$RUN_UNIT_TEST_WITH_IOS_SIM\" = \"YES\" ]; then\ntest_bundle_path=\"$BUILT_PRODUCTS_DIR/$PRODUCT_NAME.$WRAPPER_EXTENSION\"\nios-sim launch \"$(dirname \"$TEST_HOST\")\" --setenv DYLD_INSERT_LIBRARIES=/../../Library/PrivateFrameworks/IDEBundleInjection.framework/IDEBundleInjection --setenv XCInjectBundle=\"$test_bundle_path\" --setenv XCInjectBundleInto=\"$TEST_HOST\" --args -SenTest All \"$test_bundle_path\"\necho \"Finished running tests with ios-sim\"\nelse\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\nfi";
+ };
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -4879,6 +4978,7 @@
1D3623260D0F684500981E51 /* LinphoneAppDelegate.m in Sources */,
22F2508E107141E100AC9B3F /* DialerViewController.m in Sources */,
22E0A822111C44E100B04932 /* AboutViewController.m in Sources */,
+ 631C4FB119D2A8F2004BFE77 /* UIDigitButtonLongPlus.m in Sources */,
22E0A824111C44E100B04932 /* ConsoleViewController.m in Sources */,
2248E90E12F7E4CF00220D9C /* UIDigitButton.m in Sources */,
2214EB7A12F846B1002A5394 /* UICallButton.m in Sources */,
@@ -4951,6 +5051,7 @@
D3807FF615C2894A005BE9BC /* IASKSpecifier.m in Sources */,
D3807FF815C2894A005BE9BC /* IASKPSSliderSpecifierViewCell.m in Sources */,
D3807FFA15C2894A005BE9BC /* IASKPSTextFieldSpecifierViewCell.m in Sources */,
+ 631C4FB719D2C3A6004BFE77 /* UIDigitButtonLongVoiceMail.m in Sources */,
D3807FFC15C2894A005BE9BC /* IASKPSTitleValueSpecifierViewCell.m in Sources */,
D3807FFE15C2894A005BE9BC /* IASKSlider.m in Sources */,
D380800015C2894A005BE9BC /* IASKSwitch.m in Sources */,
@@ -4978,6 +5079,7 @@
22D8F145147548E2008C97DB /* LinphoneAppDelegate.m in Sources */,
22D8F146147548E2008C97DB /* DialerViewController.m in Sources */,
22D8F14A147548E2008C97DB /* AboutViewController.m in Sources */,
+ 631C4FB219D2A8F2004BFE77 /* UIDigitButtonLongPlus.m in Sources */,
22D8F14B147548E2008C97DB /* ConsoleViewController.m in Sources */,
22D8F14C147548E2008C97DB /* UIDigitButton.m in Sources */,
22D8F14E147548E2008C97DB /* UICallButton.m in Sources */,
@@ -5050,6 +5152,7 @@
D3807FF715C2894A005BE9BC /* IASKSpecifier.m in Sources */,
D3807FF915C2894A005BE9BC /* IASKPSSliderSpecifierViewCell.m in Sources */,
D3807FFB15C2894A005BE9BC /* IASKPSTextFieldSpecifierViewCell.m in Sources */,
+ 631C4FB819D2C3A6004BFE77 /* UIDigitButtonLongVoiceMail.m in Sources */,
D3807FFD15C2894A005BE9BC /* IASKPSTitleValueSpecifierViewCell.m in Sources */,
D3807FFF15C2894A005BE9BC /* IASKSlider.m in Sources */,
D380800115C2894A005BE9BC /* IASKSwitch.m in Sources */,
@@ -5069,6 +5172,16 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ F08F118019C09C6A007D70C2 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F08F119D19C0A65B007D70C2 /* NSObject+DTRuntime.m in Sources */,
+ F08F118F19C09C6B007D70C2 /* LinphoneTester_Tests.m in Sources */,
+ F08F11A019C0A6CB007D70C2 /* DTObjectBlockExecutor.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
F0BB8BD11936208100974404 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@@ -5104,6 +5217,11 @@
name = NinePatch;
targetProxy = D3B90E1C15C2CBCD00F64F8C /* PBXContainerItemProxy */;
};
+ F08F119219C09C6B007D70C2 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = F0BB8BD41936208100974404 /* LinphoneTester */;
+ targetProxy = F08F119119C09C6B007D70C2 /* PBXContainerItemProxy */;
+ };
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
@@ -5367,6 +5485,14 @@
name = "IncomingCallViewController~ipad.xib";
sourceTree = "";
};
+ F08F118B19C09C6B007D70C2 /* InfoPlist.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ F08F118C19C09C6B007D70C2 /* en */,
+ );
+ name = InfoPlist.strings;
+ sourceTree = "";
+ };
F0BB8BDC1936208100974404 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
@@ -5391,14 +5517,6 @@
name = Main_iPad.storyboard;
sourceTree = "";
};
- F0BB8C001936208200974404 /* InfoPlist.strings */ = {
- isa = PBXVariantGroup;
- children = (
- F0BB8C011936208200974404 /* en */,
- );
- name = InfoPlist.strings;
- sourceTree = "";
- };
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
@@ -5442,9 +5560,10 @@
ORDER_FILE = "";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = linphone;
- PROVISIONING_PROFILE = "";
+ PROVISIONING_PROFILE = "384d6da1-05db-4d21-ba10-ec946478a862";
SKIP_INSTALL = NO;
TARGETED_DEVICE_FAMILY = "1,2";
+ WARNING_CFLAGS = "-Werror=objc-method-access";
};
name = Debug;
};
@@ -5510,9 +5629,10 @@
ORDER_FILE = "";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = linphone;
- PROVISIONING_PROFILE = "";
+ PROVISIONING_PROFILE = "3732314a-627f-40fe-a089-235a74464861";
SKIP_INSTALL = NO;
TARGETED_DEVICE_FAMILY = "1,2";
+ WARNING_CFLAGS = "-Werror=objc-method-access";
};
name = DistributionAdhoc;
};
@@ -5735,9 +5855,10 @@
ORDER_FILE = "";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = linphone;
- PROVISIONING_PROFILE = "";
+ PROVISIONING_PROFILE = "b9cdf249-07ad-4301-af2d-b3867137d57b";
SKIP_INSTALL = NO;
TARGETED_DEVICE_FAMILY = "1,2";
+ WARNING_CFLAGS = "-Werror=objc-method-access";
};
name = Release;
};
@@ -5803,9 +5924,10 @@
ORDER_FILE = "";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = linphone;
- PROVISIONING_PROFILE = "";
+ PROVISIONING_PROFILE = "b9cdf249-07ad-4301-af2d-b3867137d57b";
SKIP_INSTALL = NO;
TARGETED_DEVICE_FAMILY = "1,2";
+ WARNING_CFLAGS = "-Werror=objc-method-access";
};
name = Distribution;
};
@@ -5833,6 +5955,212 @@
};
name = Debug;
};
+ F08F119419C09C6B007D70C2 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/LinphoneTester.app/LinphoneTester";
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(SDKROOT)/Developer/Library/Frameworks",
+ "$(inherited)",
+ "$(DEVELOPER_FRAMEWORKS_DIR)",
+ );
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "LinphoneTester Tests/LinphoneTester Tests-Prefix.pch";
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ HEADER_SEARCH_PATHS = (
+ "liblinphone-sdk/apple-darwin/include",
+ Classes/Utils/NinePatch/,
+ Classes/Utils/XMLRPC/,
+ );
+ INFOPLIST_FILE = "LinphoneTester Tests/LinphoneTester Tests-Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 7.1;
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib",
+ "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins",
+ );
+ ONLY_ACTIVE_ARCH = YES;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE = "";
+ TEST_HOST = "$(BUNDLE_LOADER)";
+ WRAPPER_EXTENSION = xctest;
+ };
+ name = Debug;
+ };
+ F08F119519C09C6B007D70C2 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/LinphoneTester.app/LinphoneTester";
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = YES;
+ ENABLE_NS_ASSERTIONS = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(SDKROOT)/Developer/Library/Frameworks",
+ "$(inherited)",
+ "$(DEVELOPER_FRAMEWORKS_DIR)",
+ );
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "LinphoneTester Tests/LinphoneTester Tests-Prefix.pch";
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ HEADER_SEARCH_PATHS = (
+ "liblinphone-sdk/apple-darwin/include",
+ Classes/Utils/NinePatch/,
+ Classes/Utils/XMLRPC/,
+ );
+ INFOPLIST_FILE = "LinphoneTester Tests/LinphoneTester Tests-Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 7.1;
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib",
+ "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins",
+ );
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE = "";
+ TEST_HOST = "$(BUNDLE_LOADER)";
+ VALIDATE_PRODUCT = YES;
+ WRAPPER_EXTENSION = xctest;
+ };
+ name = Release;
+ };
+ F08F119619C09C6B007D70C2 /* Distribution */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/LinphoneTester.app/LinphoneTester";
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = YES;
+ ENABLE_NS_ASSERTIONS = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(SDKROOT)/Developer/Library/Frameworks",
+ "$(inherited)",
+ "$(DEVELOPER_FRAMEWORKS_DIR)",
+ );
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "LinphoneTester Tests/LinphoneTester Tests-Prefix.pch";
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ HEADER_SEARCH_PATHS = (
+ "liblinphone-sdk/apple-darwin/include",
+ Classes/Utils/NinePatch/,
+ Classes/Utils/XMLRPC/,
+ );
+ INFOPLIST_FILE = "LinphoneTester Tests/LinphoneTester Tests-Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 7.1;
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib",
+ "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins",
+ );
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE = "";
+ TEST_HOST = "$(BUNDLE_LOADER)";
+ VALIDATE_PRODUCT = YES;
+ WRAPPER_EXTENSION = xctest;
+ };
+ name = Distribution;
+ };
+ F08F119719C09C6B007D70C2 /* DistributionAdhoc */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/LinphoneTester.app/LinphoneTester";
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = YES;
+ ENABLE_NS_ASSERTIONS = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(SDKROOT)/Developer/Library/Frameworks",
+ "$(inherited)",
+ "$(DEVELOPER_FRAMEWORKS_DIR)",
+ );
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "LinphoneTester Tests/LinphoneTester Tests-Prefix.pch";
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ HEADER_SEARCH_PATHS = (
+ "liblinphone-sdk/apple-darwin/include",
+ Classes/Utils/NinePatch/,
+ Classes/Utils/XMLRPC/,
+ );
+ INFOPLIST_FILE = "LinphoneTester Tests/LinphoneTester Tests-Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 7.1;
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib",
+ "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins",
+ );
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE = "";
+ TEST_HOST = "$(BUNDLE_LOADER)";
+ VALIDATE_PRODUCT = YES;
+ WRAPPER_EXTENSION = xctest;
+ };
+ name = DistributionAdhoc;
+ };
F0BB8C061936208200974404 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -5850,6 +6178,10 @@
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(DEVELOPER_FRAMEWORKS_DIR)",
+ );
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
@@ -5871,7 +6203,7 @@
Classes/Utils/XMLRPC/,
);
INFOPLIST_FILE = "LinphoneTester/LinphoneTester-Info.plist";
- IPHONEOS_DEPLOYMENT_TARGET = 6.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 7.0;
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib",
@@ -5879,7 +6211,7 @@
);
ONLY_ACTIVE_ARCH = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
- PROVISIONING_PROFILE = "72278EC2-F54D-4717-86AD-08D6E2AEC22B";
+ PROVISIONING_PROFILE = "b16cf102-d1d6-44ea-80ce-ef7337931580";
WRAPPER_EXTENSION = app;
};
name = Debug;
@@ -5902,6 +6234,10 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
ENABLE_NS_ASSERTIONS = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(DEVELOPER_FRAMEWORKS_DIR)",
+ );
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "LinphoneTester/LinphoneTester-Prefix.pch";
@@ -5916,14 +6252,14 @@
Classes/Utils/XMLRPC/,
);
INFOPLIST_FILE = "LinphoneTester/LinphoneTester-Info.plist";
- IPHONEOS_DEPLOYMENT_TARGET = 6.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 7.0;
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib",
"$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins",
);
PRODUCT_NAME = "$(TARGET_NAME)";
- PROVISIONING_PROFILE = "72278EC2-F54D-4717-86AD-08D6E2AEC22B";
+ PROVISIONING_PROFILE = "b16cf102-d1d6-44ea-80ce-ef7337931580";
VALIDATE_PRODUCT = YES;
WRAPPER_EXTENSION = app;
};
@@ -5947,6 +6283,10 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
ENABLE_NS_ASSERTIONS = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(DEVELOPER_FRAMEWORKS_DIR)",
+ );
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "LinphoneTester/LinphoneTester-Prefix.pch";
@@ -5961,14 +6301,14 @@
Classes/Utils/XMLRPC/,
);
INFOPLIST_FILE = "LinphoneTester/LinphoneTester-Info.plist";
- IPHONEOS_DEPLOYMENT_TARGET = 6.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 7.0;
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib",
"$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins",
);
PRODUCT_NAME = "$(TARGET_NAME)";
- PROVISIONING_PROFILE = "72278EC2-F54D-4717-86AD-08D6E2AEC22B";
+ PROVISIONING_PROFILE = "b16cf102-d1d6-44ea-80ce-ef7337931580";
VALIDATE_PRODUCT = YES;
WRAPPER_EXTENSION = app;
};
@@ -5992,6 +6332,10 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
ENABLE_NS_ASSERTIONS = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(DEVELOPER_FRAMEWORKS_DIR)",
+ );
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "LinphoneTester/LinphoneTester-Prefix.pch";
@@ -6006,14 +6350,14 @@
Classes/Utils/XMLRPC/,
);
INFOPLIST_FILE = "LinphoneTester/LinphoneTester-Info.plist";
- IPHONEOS_DEPLOYMENT_TARGET = 6.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 7.0;
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib",
"$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins",
);
PRODUCT_NAME = "$(TARGET_NAME)";
- PROVISIONING_PROFILE = "72278EC2-F54D-4717-86AD-08D6E2AEC22B";
+ PROVISIONING_PROFILE = "b16cf102-d1d6-44ea-80ce-ef7337931580";
VALIDATE_PRODUCT = YES;
WRAPPER_EXTENSION = app;
};
@@ -6055,6 +6399,17 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
+ F08F119319C09C6B007D70C2 /* Build configuration list for PBXNativeTarget "LinphoneTester Tests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ F08F119419C09C6B007D70C2 /* Debug */,
+ F08F119519C09C6B007D70C2 /* Release */,
+ F08F119619C09C6B007D70C2 /* Distribution */,
+ F08F119719C09C6B007D70C2 /* DistributionAdhoc */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Debug;
+ };
F0BB8C051936208200974404 /* Build configuration list for PBXNativeTarget "LinphoneTester" */ = {
isa = XCConfigurationList;
buildConfigurations = (
diff --git a/linphone.xcodeproj/xcshareddata/xcschemes/LinphoneTester.xcscheme b/linphone.xcodeproj/xcshareddata/xcschemes/LinphoneTester.xcscheme
new file mode 100644
index 000000000..00754381c
--- /dev/null
+++ b/linphone.xcodeproj/xcshareddata/xcschemes/LinphoneTester.xcscheme
@@ -0,0 +1,96 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/linphone.xcodeproj/xcshareddata/xcschemes/linphone.xcscheme b/linphone.xcodeproj/xcshareddata/xcschemes/linphone.xcscheme
new file mode 100644
index 000000000..69fececb1
--- /dev/null
+++ b/linphone.xcodeproj/xcshareddata/xcschemes/linphone.xcscheme
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/main.m b/main.m
index 878eadce7..26996ff51 100644
--- a/main.m
+++ b/main.m
@@ -18,6 +18,7 @@
*/
#import
+#import "LinphoneAppDelegate.h"
#ifdef DEBUG
@@ -35,7 +36,7 @@ int main(int argc, char *argv[]) {
NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
#endif
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
- int retVal = UIApplicationMain(argc, argv, nil, nil);
+ int retVal = UIApplicationMain(argc, argv, nil, NSStringFromClass([LinphoneAppDelegate class]));
[pool release];
return retVal;
}
diff --git a/submodules/belle-sip b/submodules/belle-sip
index ee99cb136..eee5149dd 160000
--- a/submodules/belle-sip
+++ b/submodules/belle-sip
@@ -1 +1 @@
-Subproject commit ee99cb136b23558faadab3b0c654561f4a92e371
+Subproject commit eee5149dde1ab04249e8d3d83676fa15d0ef78b6
diff --git a/submodules/build/Makefile b/submodules/build/Makefile
index ddd81d4e9..e3087adb3 100644
--- a/submodules/build/Makefile
+++ b/submodules/build/Makefile
@@ -1,5 +1,5 @@
############################################################################
-# Makefile
+# Makefile
# Copyright (C) 2009 Belledonne Communications,Grenoble France
#
############################################################################
@@ -56,7 +56,7 @@ endif
ifeq ($(enable_gpl_third_parties),yes)
warning:
- @echo
+ @echo
@echo "***************************************************************************"
@echo "***************************************************************************"
@echo "*****CAUTION, this liblinphone SDK is built using 3rd party GPL code ******"
@@ -68,7 +68,7 @@ warning:
@echo "***************************************************************************"
else
warning:
- @echo
+ @echo
@echo "*****************************************************************"
@echo "*****************************************************************"
@echo "*****Linphone SDK without 3rd party GPL software ******"
@@ -84,17 +84,17 @@ LINPHONE_OPTIONS=enable_gpl_third_parties=$(enable_gpl_third_parties) \
enable_debug=$(enable_debug) enable_ffmpeg=$(enable_ffmpeg) enable_tunnel=$(enable_tunnel)
-armv7-%:
+armv7-%:
make -f builder-iphone-os.mk $(LINPHONE_OPTIONS) $*
-armv7s-%:
+armv7s-%:
make -f builder-iphone-os.mk host=armv7s-apple-darwin $(LINPHONE_OPTIONS) $*
-simu-%:
+simu-%:
make -f builder-iphone-simulator.mk $(LINPHONE_OPTIONS) $*
-build-% clean-% veryclean-%:
+build-% clean-% veryclean-%:
make -f builder-iphone-simulator.mk $(LINPHONE_OPTIONS) $@ \
&& make -f builder-iphone-os.mk $(LINPHONE_OPTIONS) $@ \
&& make -f builder-iphone-os.mk host=armv7s-apple-darwin $(LINPHONE_OPTIONS) $@
@@ -106,8 +106,11 @@ broadcast_%:
&& make -f builder-iphone-os.mk $(LINPHONE_OPTIONS) $* \
&& make -f builder-iphone-os.mk host=armv7s-apple-darwin $(LINPHONE_OPTIONS) $*
-sdk:
- make -f builder-iphone-os.mk delivery-sdk
+sdk:
+ make -f builder-iphone-os.mk delivery-sdk
+
+download-sdk:
+ make -f builder-iphone-os.mk download-sdk
build: broadcast_all sdk
@@ -119,7 +122,7 @@ veryclean: broadcast_veryclean
zipres:
- @tar -C ../.. -czf ../../ios_assets.tar.gz Resources iTunesArtwork
+ @tar -C ../.. -czf ../../ios_assets.tar.gz Resources iTunesArtwork
@echo Archive 'ios_assets.tar.gz' placed in root directory
help:
diff --git a/submodules/build/builder-iphone-os.mk b/submodules/build/builder-iphone-os.mk
index 066387b54..c0288a954 100644
--- a/submodules/build/builder-iphone-os.mk
+++ b/submodules/build/builder-iphone-os.mk
@@ -1,5 +1,5 @@
############################################################################
-# builder-generic.mk
+# builder-generic.mk
# Copyright (C) 2009 Belledonne Communications,Grenoble France
#
############################################################################
@@ -19,7 +19,7 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
############################################################################
-
+
host?=armv7-apple-darwin
config_site:=iphone-config.site
library_mode:= --disable-shared --enable-static
@@ -40,7 +40,7 @@ linphone_configure_controls = \
--disable-tools \
--enable-msg-storage=yes
-
+
#path
BUILDER_SRC_DIR?=$(shell pwd)/../
ifeq ($(enable_debug),yes)
@@ -82,19 +82,19 @@ else
SWITCHES += disable_tunnel
endif
-ifeq ($(enable_gpl_third_parties),yes)
+ifeq ($(enable_gpl_third_parties),yes)
SWITCHES+= enable_gpl_third_parties
-
+
ifeq ($(enable_ffmpeg), yes)
- linphone_configure_controls+= --enable-ffmpeg
+ linphone_configure_controls+= --enable-ffmpeg
SWITCHES += enable_ffmpeg
else
- linphone_configure_controls+= --disable-ffmpeg
+ linphone_configure_controls+= --disable-ffmpeg
SWITCHES += disable_ffmpeg
endif
else # !enable gpl
- linphone_configure_controls+= --disable-ffmpeg
+ linphone_configure_controls+= --disable-ffmpeg
SWITCHES += disable_gpl_third_parties disable_ffmpeg
endif
@@ -107,12 +107,10 @@ $(LINPHONE_BUILD_DIR)/enable_% $(LINPHONE_BUILD_DIR)/disable_%:
mkdir -p $(LINPHONE_BUILD_DIR)
cd $(LINPHONE_BUILD_DIR) && rm -f *able_$*
touch $@
- cd $(LINPHONE_BUILD_DIR) && rm -f Makefile && rm -f oRTP/Makefile && rm -f mediastreamer2/Makefile
+ cd $(LINPHONE_BUILD_DIR) && rm -f Makefile && rm -f oRTP/Makefile && rm -f mediastreamer2/Makefile
# end of switches parsing
-osip_dir=externals/osip
-eXosip_dir=externals/exosip
speex_dir=externals/speex
gsm_dir=externals/gsm
@@ -124,12 +122,12 @@ LIBILBC_BUILD_DIR:=$(BUILDER_BUILD_DIR)/libilbc-rfc3951
ifneq (,$(findstring arm,$(host)))
#SPEEX_CONFIGURE_OPTION := --enable-fixed-point --disable-float-api
- CFLAGS := $(CFLAGS) -marm
+ CFLAGS := $(CFLAGS) -marm
SPEEX_CONFIGURE_OPTION := --disable-float-api --enable-arm5e-asm --enable-fixed-point
endif
ifneq (,$(findstring armv7,$(host)))
- SPEEX_CONFIGURE_OPTION += --enable-armv7neon-asm
+ SPEEX_CONFIGURE_OPTION += --enable-armv7neon-asm
endif
clean-makefile: clean-makefile-linphone clean-makefile-msbcg729
@@ -143,7 +141,7 @@ veryclean: veryclean-linphone veryclean-msbcg729
# list of the submodules to build, the order is important
MS_MODULES := msilbc libilbc msamr mssilk msx264 mswebrtc msopenh264
-SUBMODULES_LIST := polarssl
+SUBMODULES_LIST := polarssl
ifeq ($(enable_tunnel),yes)
SUBMODULES_LIST += tunnel
@@ -178,16 +176,16 @@ $(LINPHONE_BUILD_DIR)/Makefile: $(LINPHONE_SRC_DIR)/configure
PKG_CONFIG_LIBDIR=$(prefix)/lib/pkgconfig CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) \
$(LINPHONE_SRC_DIR)/configure -prefix=$(prefix) --host=$(host) ${library_mode} \
${linphone_configure_controls}
-
+
#libphone only (asume dependencies are met)
-build-liblinphone: $(LINPHONE_BUILD_DIR)/Makefile
+build-liblinphone: $(LINPHONE_BUILD_DIR)/Makefile
cd $(LINPHONE_BUILD_DIR) && export PKG_CONFIG_LIBDIR=$(prefix)/lib/pkgconfig export CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) make newdate && make && make install
-clean-makefile-liblinphone:
- cd $(LINPHONE_BUILD_DIR) && rm -f Makefile && rm -f oRTP/Makefile && rm -f mediastreamer2/Makefile
-
-clean-liblinphone:
+clean-makefile-liblinphone:
+ cd $(LINPHONE_BUILD_DIR) && rm -f Makefile && rm -f oRTP/Makefile && rm -f mediastreamer2/Makefile
+
+clean-liblinphone:
cd $(LINPHONE_BUILD_DIR) && make clean
#speex
@@ -219,6 +217,7 @@ clean-makefile-speex:
build-libgsm:
cp -rf $(BUILDER_SRC_DIR)/$(gsm_dir) $(BUILDER_BUILD_DIR)/$(gsm_dir)
+ rm -rf $(BUILDER_BUILD_DIR)/$(gsm_dir)/.git
rm -f $(prefix)/lib/libgsm.a
rm -rf $(prefix)/include/gsm
cd $(BUILDER_BUILD_DIR)/$(gsm_dir)\
@@ -230,7 +229,7 @@ clean-libgsm:
cd $(BUILDER_BUILD_DIR)/$(gsm_dir)\
&& make clean
-veryclean-libgsm:
+veryclean-libgsm:
-cd $(BUILDER_BUILD_DIR)/$(gsm_dir) \
&& make uninstall
@@ -327,14 +326,22 @@ delivery-sdk: multi-arch
liblinphone-tutorials \
-x liblinphone-tutorials/hello-world/build\* \
-x liblinphone-tutorials/hello-world/hello-world.xcodeproj/*.pbxuser \
- -x liblinphone-tutorials/hello-world/hello-world.xcodeproj/*.mode1v3
+ -x liblinphone-tutorials/hello-world/hello-world.xcodeproj/*.mode1v3
+
+download-sdk:
+ cd $(BUILDER_SRC_DIR)/../
+ rm -fr liblinphone-iphone-sdk-latest*
+ wget http://linphone.org/snapshots/ios/liblinphone-iphone-sdk-latest.zip
+ unzip -o -q liblinphone-iphone-sdk-latest.zip
+ rm -fr ../../liblinphone-sdk/
+ mv liblinphone-sdk ../..
.PHONY delivery:
cd $(BUILDER_SRC_DIR)/../../ \
&& zip -r $(BUILDER_SRC_DIR)/linphone-iphone.zip \
linphone-iphone \
-x linphone-iphone/build\* \
- --exclude linphone-iphone/.git\* --exclude \*.[od] --exclude \*.so.\* --exclude \*.a --exclude linphone-iphone/liblinphone-sdk/apple-darwin/\* --exclude \*.lo
+ --exclude linphone-iphone/.git\* --exclude \*.[od] --exclude \*.so.\* --exclude \*.a --exclude linphone-iphone/liblinphone-sdk/apple-darwin/\* --exclude \*.lo
ipa:
cd $(BUILDER_SRC_DIR)/../ \
diff --git a/submodules/build/builders.d/opus.mk b/submodules/build/builders.d/opus.mk
index f0e6dcf32..54d816d22 100644
--- a/submodules/build/builders.d/opus.mk
+++ b/submodules/build/builders.d/opus.mk
@@ -24,10 +24,10 @@ enable_opus?=yes
libopus_configure_options=--disable-extra-programs --disable-doc
ifneq (,$(findstring armv7,$(host)))
- libopus_configure_options+= --enable-fixed-point --disable-asm
+ libopus_configure_options+= --enable-fixed-point
endif
ifneq (,$(findstring armv7s,$(host)))
- libopus_configure_options+= --enable-fixed-point --disable-asm
+ libopus_configure_options+= --enable-fixed-point
endif
$(BUILDER_SRC_DIR)/$(opus_dir)/configure:
diff --git a/submodules/build/builders.d/x264.patch b/submodules/build/builders.d/x264.patch
index 60ffc6701..62bd0789e 100644
--- a/submodules/build/builders.d/x264.patch
+++ b/submodules/build/builders.d/x264.patch
@@ -134,3 +134,16 @@ index e851562..c159f9e 100644
movlt r0, #0
bx lr
.endfunc
+diff --git a/configure b/configure
+index 250b0ac..af69d44 100755
+--- a/configure
++++ b/configure
+@@ -456,7 +456,7 @@ case $host_os in
+ ;;
+ darwin*)
+ SYS="MACOSX"
+- CFLAGS="$CFLAGS -falign-loops=16"
++ CFLAGS="$CFLAGS"
+ libm="-lm"
+ if [ "$pic" = "no" ]; then
+ cc_check "" -mdynamic-no-pic && CFLAGS="$CFLAGS -mdynamic-no-pic"
diff --git a/submodules/build/iphone-config.site b/submodules/build/iphone-config.site
index 995023e4a..c62de78fe 100644
--- a/submodules/build/iphone-config.site
+++ b/submodules/build/iphone-config.site
@@ -1,7 +1,7 @@
# -*- shell-script -*-
-SDK_VERSION_MAJOR=4
-SDK_VERSION=4.0
+SDK_VERSION_MAJOR=5
+SDK_VERSION=5.0
MCPU=""
CLANG_TARGET_SPECIFIER=miphoneos-version-min
if test "${host_alias}" = "i386-apple-darwin" ; then
diff --git a/submodules/bzrtp b/submodules/bzrtp
index 8ceda7ef0..0948658db 160000
--- a/submodules/bzrtp
+++ b/submodules/bzrtp
@@ -1 +1 @@
-Subproject commit 8ceda7ef0d35130057affc2e5a61c0667cde15aa
+Subproject commit 0948658db85a7c9933ed2d39a159239d9ee5c734
diff --git a/submodules/externals/antlr3 b/submodules/externals/antlr3
index 20985f63c..489f375fb 160000
--- a/submodules/externals/antlr3
+++ b/submodules/externals/antlr3
@@ -1 +1 @@
-Subproject commit 20985f63cb691f7ea0bdf9ccf7d5cbfda055e060
+Subproject commit 489f375fb391cb70d82b56f509c39cbf7fa0b706
diff --git a/submodules/externals/opus b/submodules/externals/opus
index fcecd29ab..da97db1ca 160000
--- a/submodules/externals/opus
+++ b/submodules/externals/opus
@@ -1 +1 @@
-Subproject commit fcecd29abf32164326e568acdcdf7d8e877b33b1
+Subproject commit da97db1ca1f92592af3534c9a2596da0e9a009ca
diff --git a/submodules/externals/polarssl b/submodules/externals/polarssl
index e9f7b4487..deb4df478 160000
--- a/submodules/externals/polarssl
+++ b/submodules/externals/polarssl
@@ -1 +1 @@
-Subproject commit e9f7b4487464909a786b156b149de7769d1df3a2
+Subproject commit deb4df4789494ecbfd55926ec3e03e2f736899c5
diff --git a/submodules/linphone b/submodules/linphone
index 3c32fd439..2479a567a 160000
--- a/submodules/linphone
+++ b/submodules/linphone
@@ -1 +1 @@
-Subproject commit 3c32fd43972ad9560f33e1f056ad7be694d8e685
+Subproject commit 2479a567a5a49a7a63406b3b1bf3f7a536a03d54
diff --git a/submodules/msopenh264 b/submodules/msopenh264
index 7a8738cd1..e60a95bfa 160000
--- a/submodules/msopenh264
+++ b/submodules/msopenh264
@@ -1 +1 @@
-Subproject commit 7a8738cd1f034222f83ffa3be8a411319b1a37fa
+Subproject commit e60a95bfa38019635607b14964e2a3c1ee067248
diff --git a/submodules/msx264 b/submodules/msx264
index ee2a0f6f0..05b55211c 160000
--- a/submodules/msx264
+++ b/submodules/msx264
@@ -1 +1 @@
-Subproject commit ee2a0f6f0904995177434292a7a0fb4c51632e4e
+Subproject commit 05b55211c6fe7eebef485a00a60c66cbe1394907