diff --git a/Classes/LinphoneAppDelegate.h b/Classes/LinphoneAppDelegate.h index f5e9508a1..b2e027c43 100644 --- a/Classes/LinphoneAppDelegate.h +++ b/Classes/LinphoneAppDelegate.h @@ -20,7 +20,6 @@ #import #import -#import "CoreTelephony/CTCallCenter.h" #define DIALER_TAB_INDEX 1 #define CONTACTS_TAB_INDEX 2 @@ -40,13 +39,10 @@ IBOutlet PhoneViewController* myPhoneViewController; CallHistoryTableViewController* myCallHistoryTableViewController; ContactPickerDelegate* myContactPickerDelegate; - - CTCallCenter* callCenter; } - (void) loadDefaultSettings:(NSDictionary *) appDefaults; -(void) setupUI; --(void) setupGSMInteraction; -(void) startApplication; diff --git a/Classes/LinphoneAppDelegate.m b/Classes/LinphoneAppDelegate.m index 8162f851d..f430b7873 100644 --- a/Classes/LinphoneAppDelegate.m +++ b/Classes/LinphoneAppDelegate.m @@ -46,25 +46,6 @@ int __aeabi_idiv(int a, int b) { @synthesize myPeoplePickerController; @synthesize myPhoneViewController; --(void) handleGSMCallInteration: (id) cCenter { - CTCallCenter* ct = (CTCallCenter*) cCenter; - - int callCount = [ct.currentCalls count]; - if (!callCount) { - NSLog(@"No GSM call -> enabling SIP calls"); - linphone_core_set_max_calls([LinphoneManager getLc], 3); - } else { - NSLog(@"%d GSM call(s) -> disabling SIP calls", callCount); - /* pause current call, if any */ - LinphoneCall* call = linphone_core_get_current_call([LinphoneManager getLc]); - if (call) { - NSLog(@"Pausing SIP call"); - linphone_core_pause_call([LinphoneManager getLc], call); - } - linphone_core_set_max_calls([LinphoneManager getLc], 0); - } -} - -(void)applicationWillResignActive:(UIApplication *)application { LinphoneCore* lc = [LinphoneManager getLc]; LinphoneCall* call = linphone_core_get_current_call(lc); @@ -84,13 +65,7 @@ int __aeabi_idiv(int a, int b) { } - (void)applicationDidEnterBackground:(UIApplication *)application { if (![[LinphoneManager instance] enterBackgroundMode]) { - // destroying eventHandler if app cannot go in background. - // Otherwise if a GSM call happen and Linphone is resumed, - // the handler will be called before LinphoneCore is built. - // Then handler will be restored in appDidBecomeActive cb - callCenter.callEventHandler = nil; - [callCenter release]; - callCenter = nil; + } } - (void)applicationDidBecomeActive:(UIApplication *)application { @@ -105,18 +80,6 @@ int __aeabi_idiv(int a, int b) { [[LinphoneManager instance] becomeActive]; - if (callCenter == nil) { - callCenter = [[CTCallCenter alloc] init]; - callCenter.callEventHandler = ^(CTCall* call) { - // post on main thread - [self performSelectorOnMainThread:@selector(handleGSMCallInteration:) - withObject:callCenter - waitUntilDone:YES]; - }; - } - // check call state at startup - [self handleGSMCallInteration:callCenter]; - LinphoneCore* lc = [LinphoneManager getLc]; LinphoneCall* call = linphone_core_get_current_call(lc); if (call == NULL) @@ -213,16 +176,6 @@ int __aeabi_idiv(int a, int b) { [UIDevice currentDevice].batteryMonitoringEnabled = YES; } --(void) setupGSMInteraction { - callCenter = [[CTCallCenter alloc] init]; - callCenter.callEventHandler = ^(CTCall* call) { - // post on main thread - [self performSelectorOnMainThread:@selector(handleGSMCallInteration:) - withObject:callCenter - waitUntilDone:YES]; - }; -} - - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys: @"NO", @"enable_first_login_view_preference", // @@ -258,8 +211,6 @@ int __aeabi_idiv(int a, int b) { [[LinphoneManager instance] startLibLinphone]; [[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeSound]; - - [self setupGSMInteraction]; } diff --git a/Classes/LinphoneUI/LinphoneManager.h b/Classes/LinphoneUI/LinphoneManager.h index 691ebd14f..8e5932e73 100644 --- a/Classes/LinphoneUI/LinphoneManager.h +++ b/Classes/LinphoneUI/LinphoneManager.h @@ -23,6 +23,7 @@ #include "linphonecore.h" #import "LogView.h" #import "LinphoneUIDelegates.h" +#import "CoreTelephony/CTCallCenter.h" typedef enum _Connectivity { wifi, @@ -66,6 +67,7 @@ typedef struct _LinphoneCallAppData { const char* backCamId; NSDictionary* currentSettings; + CTCallCenter* callCenter; @public CallContext currentCallContextBeforeGoingBackground; diff --git a/Classes/LinphoneUI/LinphoneManager.m b/Classes/LinphoneUI/LinphoneManager.m index 8345c50d4..26be8f942 100644 --- a/Classes/LinphoneUI/LinphoneManager.m +++ b/Classes/LinphoneUI/LinphoneManager.m @@ -820,7 +820,16 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach } } -(void) destroyLibLinphone { - [mIterateTimer invalidate]; + [mIterateTimer invalidate]; + + // destroying eventHandler if app cannot go in background. + // Otherwise if a GSM call happen and Linphone is resumed, + // the handler will be called before LinphoneCore is built. + // Then handler will be restored in appDidBecomeActive cb + callCenter.callEventHandler = nil; + [callCenter release]; + callCenter = nil; + AVAudioSession *audioSession = [AVAudioSession sharedInstance]; [audioSession setDelegate:nil]; if (theLinphoneCore != nil) { //just in case application terminate before linphone core initialization @@ -961,6 +970,8 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach #if HAVE_G729 libmsbcg729_init(); // load g729 plugin #endif + + [self setupGSMInteraction]; /* Initialize linphone core*/ NSLog(@"Create linphonecore"); @@ -1070,6 +1081,13 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach } /*IOS specific*/ linphone_core_start_dtmf_stream(theLinphoneCore); + + //call center is unrelialable on the long run, so we change it each time the application is resumed. To avoid zombie GSM call + [self setupGSMInteraction]; + + //to make sure presence status is correct + if ([callCenter currentCalls]==nil) + linphone_core_set_presence_info(theLinphoneCore, 0, nil, LinphoneStatusAltService); } -(void) registerLogView:(id) view { @@ -1088,6 +1106,7 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach ms_message("Sound interruption ended!"); //let the user resume the call manually. } + +(BOOL) runningOnIpad { #ifdef UI_USER_INTERFACE_IDIOM return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad); @@ -1106,5 +1125,33 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach ms_message("UI - '%s' pressed", name); } +#pragma GSM management +-(void) setupGSMInteraction { + if (callCenter != nil) + [callCenter release]; + + callCenter = [[CTCallCenter alloc] init]; + callCenter.callEventHandler = ^(CTCall* call) { + // post on main thread + [self performSelectorOnMainThread:@selector(handleGSMCallInteration:) + withObject:callCenter + waitUntilDone:YES]; + }; +} + +-(void) handleGSMCallInteration: (id) cCenter { + CTCallCenter* ct = (CTCallCenter*) cCenter; + /* pause current call, if any */ + LinphoneCall* call = linphone_core_get_current_call(theLinphoneCore); + if ([ct currentCalls]!=nil) { + if (call) { + NSLog(@"Pausing SIP call"); + linphone_core_pause_call(theLinphoneCore, call); + } + //set current status to busy + linphone_core_set_presence_info(theLinphoneCore, 0, nil, LinphoneStatusBusy); + } else + linphone_core_set_presence_info(theLinphoneCore, 0, nil, LinphoneStatusAltService); +} @end