First functional version of remote provisioning

This commit is contained in:
Guillaume BIENKOWSKI 2014-03-13 11:51:27 +01:00
parent 3df38649f6
commit 912ca99436
10 changed files with 400 additions and 104 deletions

View file

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="4514" systemVersion="13B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<dependencies>
<deployment defaultVersion="1072" identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3747"/>
</dependencies>
<objects>
@ -15,6 +14,7 @@
<outlet property="createAccountView" destination="44" id="70"/>
<outlet property="externalAccountButton" destination="39" id="133"/>
<outlet property="externalAccountView" destination="56" id="72"/>
<outlet property="remoteProvisioningButton" destination="Kbn-dL-C5h" id="PPk-DJ-nEb"/>
<outlet property="validateAccountView" destination="101" id="112"/>
<outlet property="welcomeView" destination="21" id="28"/>
</connections>
@ -73,7 +73,7 @@
<size key="shadowOffset" width="-1" height="-1"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" id="36" userLabel="createAccountButton" customClass="UILinphoneButton">
<rect key="frame" x="33" y="141" width="255" height="50"/>
<rect key="frame" x="34" y="153" width="255" height="50"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Create linphone.org account">
<bool key="isElement" value="YES"/>
@ -91,7 +91,7 @@
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" id="38" userLabel="connectAccountButton" customClass="UILinphoneButton">
<rect key="frame" x="33" y="205" width="255" height="50"/>
<rect key="frame" x="34" y="211" width="255" height="50"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Sign in linphone.org account">
<bool key="isElement" value="YES"/>
@ -126,6 +126,24 @@
<action selector="onExternalAccountClick:" destination="-1" eventType="touchUpInside" id="43"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" id="Kbn-dL-C5h" userLabel="remoteProvisioningButton" customClass="UILinphoneButton">
<rect key="frame" x="34" y="327" width="255" height="50"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Sign in SIP account">
<bool key="isElement" value="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="boldSystem" pointSize="13"/>
<state key="normal" title="Remote Provisioning" backgroundImage="button_background_default.png">
<color key="titleColor" red="0.35686274509999999" green="0.39607843139999999" blue="0.43529411759999997" alpha="1" colorSpace="deviceRGB"/>
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<state key="highlighted" backgroundImage="button_background_over.png">
<color key="titleColor" red="0.72549019609999998" green="0.76862745099999996" blue="0.79607843140000001" alpha="1" colorSpace="deviceRGB"/>
</state>
<connections>
<action selector="onRemoteProvisioningClick:" destination="-1" eventType="touchUpInside" id="7oT-2f-Rrb"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
@ -273,6 +291,13 @@
<action selector="onSignInClick:" destination="-1" eventType="touchUpInside" id="116"/>
</connections>
</button>
<label hidden="YES" opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="105" contentMode="left" text="remote provisioning details" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" minimumFontSize="10" adjustsFontSizeToFit="NO" id="W9Y-Z9-Rmz" userLabel="remoteProvisionDetails">
<rect key="frame" x="40" y="242" width="240" height="80"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
@ -410,6 +435,19 @@
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
<view contentMode="scaleToFill" id="7Az-KG-XEW" userLabel="remoteProvisionWaitView">
<rect key="frame" x="0.0" y="0.0" width="320" height="480"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" animating="YES" style="whiteLarge" id="GG1-Sn-aIT" userLabel="activity">
<rect key="frame" x="142" y="221" width="37" height="37"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="color" white="1" alpha="1" colorSpace="calibratedWhite"/>
</activityIndicatorView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.29999999999999999" colorSpace="calibratedWhite"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
</view>
</objects>
<resources>
<image name="button_background_default.png" width="550" height="101"/>

View file

@ -48,6 +48,7 @@ extern NSString *const kLinphoneLogsUpdate;
extern NSString *const kLinphoneSettingsUpdate;
extern NSString *const kLinphoneBluetoothAvailabilityUpdate;
extern NSString *const kLinphoneConfiguringStateUpdate;
extern NSString *const kLinphoneGlobalStateUpdate;
typedef enum _NetworkType {
network_none = 0,
@ -119,6 +120,7 @@ typedef struct _LinphoneManagerSounds {
+ (NSString *)getUserAgent;
- (void)resetLinphoneCore;
- (void)startLibLinphone;
- (void)destroyLibLinphone;
- (BOOL)resignActive;

View file

@ -58,7 +58,8 @@ NSString *const kLinphoneMainViewChange = @"LinphoneMainViewChange";
NSString *const kLinphoneLogsUpdate = @"LinphoneLogsUpdate";
NSString *const kLinphoneSettingsUpdate = @"LinphoneSettingsUpdate";
NSString *const kLinphoneBluetoothAvailabilityUpdate = @"LinphoneBluetoothAvailabilityUpdate";
NSString *const kLinphoneConfiguringStateUpdate = @"LinphoneConfiguringStateUpdate";
NSString *const kLinphoneGlobalStateUpdate = @"LinphoneGlobalStateUpdate";
extern void libmsilbc_init();
@ -285,7 +286,9 @@ struct codec_name_pref_table codec_pref_table[]={
if (lStatus) {
[LinphoneLogger logc:LinphoneLoggerError format:"cannot un register route change handler [%ld]", lStatus];
}
[[NSNotificationCenter defaultCenter] removeObserver:self forKeyPath:kLinphoneGlobalStateUpdate];
[photoLibrary release];
[pendindCallIdFromRemoteNotif release];
[super dealloc];
@ -569,6 +572,53 @@ static void linphone_iphone_call_state(LinphoneCore *lc, LinphoneCall* call, Lin
static void linphone_iphone_transfer_state_changed(LinphoneCore* lc, LinphoneCall* call, LinphoneCallState state) {
}
#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];
}
-(void)onGlobalStateChanged:(LinphoneGlobalState)state withMessage:(const char*)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];
// 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];
}
}
#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];
}
-(void)onConfiguringStatusChanged:(LinphoneConfiguringState)status withMessage:(const char*)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];
// dispatch the notification asynchronously
dispatch_async(dispatch_get_main_queue(), ^(void){
[[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneConfiguringStateUpdate object:self userInfo:dict];
});
}
#pragma mark - Registration State Functions
@ -840,7 +890,9 @@ static LinphoneCoreVTable linphonec_vtable = {
.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
.is_composing_received = linphone_iphone_is_composing_received,
.configuring_status = linphone_iphone_configuring_status_changed,
.global_state_changed = linphone_iphone_global_state_changed
};
//scheduling loop
@ -859,17 +911,88 @@ static LinphoneCoreVTable linphonec_vtable = {
}
}
/** Should be called once per linphone_core_new() */
- (void)finishCoreConfiguration {
//get default config from bundle
NSString *zrtpSecretsFileName = [LinphoneManager documentFile:@"zrtp_secrets"];
const char* lRootCa = [[LinphoneManager bundleFile:@"rootca.pem"] cStringUsingEncoding:[NSString defaultCStringEncoding]];
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);
// 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]];
linphone_core_set_play_file(theLinphoneCore, lPlay);
linphone_core_set_zrtp_secrets_file(theLinphoneCore, [zrtpSecretsFileName cStringUsingEncoding:[NSString defaultCStringEncoding]]);
[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);
}
/*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;
}
}
if (![LinphoneManager isNotIphone3G]){
PayloadType *pt=linphone_core_find_payload_type(theLinphoneCore,"SILK",24000,-1);
if (pt) {
linphone_core_enable_payload_type(theLinphoneCore,pt,FALSE);
[LinphoneLogger logc:LinphoneLoggerWarning format:"SILK/24000 and video disabled on old iPhone 3G"];
}
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]]];
// Post event
NSDictionary *dict = [NSDictionary dictionaryWithObject:[NSValue valueWithPointer:theLinphoneCore]
forKey:@"core"];
[[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneCoreUpdate
object:[LinphoneManager instance]
userInfo:dict];
}
- (void)startLibLinphone {
if (theLinphoneCore != nil) {
[LinphoneLogger logc:LinphoneLoggerLog format:"linphonecore is already created"];
return;
}
//get default config from bundle
NSString* factoryConfig = [LinphoneManager bundleFile:[LinphoneManager runningOnIpad]?@"linphonerc-factory~ipad":@"linphonerc-factory"];
NSString* factoryConfig = [LinphoneManager bundleFile:[LinphoneManager runningOnIpad]?@"linphonerc-factory~ipad":@"linphonerc-factory"];
NSString *confiFileName = [LinphoneManager documentFile:@".linphonerc"];
NSString *zrtpSecretsFileName = [LinphoneManager documentFile:@"zrtp_secrets"];
const char* lRootCa = [[LinphoneManager bundleFile:@"rootca.pem"] cStringUsingEncoding:[NSString defaultCStringEncoding]];
connectivity = none;
signal(SIGPIPE, SIG_IGN);
//log management
@ -900,27 +1023,10 @@ static LinphoneCoreVTable linphonec_vtable = {
theLinphoneCore = linphone_core_new (&linphonec_vtable
, [confiFileName cStringUsingEncoding:[NSString defaultCStringEncoding]]
, [factoryConfig cStringUsingEncoding:[NSString defaultCStringEncoding]]
,self);
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];
,self /* user_data */);
fastAddressBook = [[FastAddressBook alloc] init];
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]];
linphone_core_set_play_file(theLinphoneCore, lPlay);
linphone_core_set_zrtp_secrets_file(theLinphoneCore, [zrtpSecretsFileName cStringUsingEncoding:[NSString defaultCStringEncoding]]);
[self setupNetworkReachabilityCallback];
/* 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 */
// start scheduler
mIterateTimer = [NSTimer scheduledTimerWithTimeInterval:0.02
@ -928,7 +1034,8 @@ static LinphoneCoreVTable linphonec_vtable = {
selector:@selector(iterate)
userInfo:nil
repeats:YES];
//init audio session
//init audio session
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
BOOL bAudioInputAvailable= audioSession.inputAvailable;
NSError* err;
@ -937,6 +1044,8 @@ static LinphoneCoreVTable linphonec_vtable = {
selector:@selector(audioSessionInterrupted:)
name:AVAudioSessionInterruptionNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(globalStateChangedNotificationHandler:) name:kLinphoneGlobalStateUpdate object:nil];
if( ![audioSession setActive:NO error: &err] && err ){
@ -951,55 +1060,13 @@ static LinphoneCoreVTable linphonec_vtable = {
[error show];
[error release];
}
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;
}
}
if (![LinphoneManager isNotIphone3G]){
PayloadType *pt=linphone_core_find_payload_type(theLinphoneCore,"SILK",24000,-1);
if (pt) {
linphone_core_enable_payload_type(theLinphoneCore,pt,FALSE);
[LinphoneLogger logc:LinphoneLoggerWarning format:"SILK/24000 and video disabled on old iPhone 3G"];
}
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]]];
if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]
&& [UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
//go directly to bg mode
[self resignActive];
}
// Post event
NSDictionary *dict = [NSDictionary dictionaryWithObject:[NSValue valueWithPointer:theLinphoneCore] forKey:@"core"];
[[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneCoreUpdate object:[LinphoneManager instance] userInfo:dict];
}
- (void)destroyLibLinphone {
@ -1026,6 +1093,39 @@ static LinphoneCoreVTable linphonec_vtable = {
}
}
- (void) resetLinphoneCore {
[self destroyLibLinphone];
if (theLinphoneCore != nil) {
[LinphoneLogger logc:LinphoneLoggerLog format:"linphonecore is already created"];
return;
}
[LinphoneLogger logc:LinphoneLoggerLog format:"Create linphonecore"];
NSString* factoryConfig = [LinphoneManager bundleFile:[LinphoneManager runningOnIpad]?@"linphonerc-factory~ipad":@"linphonerc-factory"];
NSString *confiFileName = [LinphoneManager documentFile:@".linphonerc"];
theLinphoneCore = linphone_core_new (&linphonec_vtable
, [confiFileName cStringUsingEncoding:[NSString defaultCStringEncoding]]
, [factoryConfig cStringUsingEncoding:[NSString defaultCStringEncoding]]
,self /* user_data */);
/* 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];
connectivity=none;
linphone_core_set_network_reachable(theLinphoneCore, FALSE);
// start scheduler
mIterateTimer = [NSTimer scheduledTimerWithTimeInterval:0.02
target:self
selector:@selector(iterate)
userInfo:nil
repeats:YES];
}
static int comp_call_id(const LinphoneCall* call , const char *callid) {
if (linphone_call_log_get_call_id(linphone_call_get_call_log(call)) == nil) {
ms_error ("no callid for call [%p]", call);

View file

@ -86,7 +86,10 @@ NSTimer *callSecurityTimer;
name:kLinphoneRegistrationUpdate
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(globalStateUpdate:)
name:kLinphoneConfiguringStateUpdate
object:nil];
[callQualityImage setHidden: true];
[callSecurityImage setHidden: true];
@ -104,7 +107,9 @@ NSTimer *callSecurityTimer;
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kLinphoneRegistrationUpdate
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kLinphoneConfiguringStateUpdate
object:nil];
if(callQualityTimer != nil) {
[callQualityTimer invalidate];
callQualityTimer = nil;
@ -124,15 +129,23 @@ NSTimer *callSecurityTimer;
[self proxyConfigUpdate:config];
}
- (void) globalStateUpdate:(NSNotification*) notif {
[self registrationUpdate:notif];
}
#pragma mark -
- (void)proxyConfigUpdate: (LinphoneProxyConfig*) config {
LinphoneRegistrationState state;
LinphoneRegistrationState state = LinphoneRegistrationNone;
NSString* message = nil;
UIImage* image = nil;
LinphoneCore* lc = [LinphoneManager getLc];
LinphoneGlobalState gstate = linphone_core_get_global_state(lc);
if (config == NULL) {
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);

View file

@ -112,7 +112,11 @@ static PhoneMainView* phoneMainViewInstance=nil;
selector:@selector(textReceived:)
name:kLinphoneTextReceived
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(onGlobalStateChanged:)
name:kLinphoneGlobalStateUpdate
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(batteryLevelChanged:)
name:UIDeviceBatteryLevelDidChangeNotification
object:nil];
@ -135,10 +139,13 @@ static PhoneMainView* phoneMainViewInstance=nil;
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kLinphoneRegistrationUpdate
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kLinphoneTextReceived
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kLinphoneConfiguringStateUpdate
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIDeviceBatteryLevelDidChangeNotification
object:nil];
[[UIDevice currentDevice] setBatteryMonitoringEnabled:NO];
@ -229,6 +236,19 @@ static PhoneMainView* phoneMainViewInstance=nil;
}
}
- (void)onGlobalStateChanged:(NSNotification*)notif {
LinphoneConfiguringState state = [[[notif userInfo] valueForKey:@"state"] integerValue];
LinphoneAppDelegate *appDelegate = (LinphoneAppDelegate *)[[UIApplication sharedApplication] delegate];
if( state == LinphoneGlobalOn && !(appDelegate.started) ){
if( [[LinphoneManager instance] lpConfigBoolForKey:@"show_login_view" forSection:@"app"] ){
WizardViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[WizardViewController compositeViewDescription]], WizardViewController);
if(controller != nil) {
[controller handleRemoteProvisioning];
}
}
}
}
- (void)callUpdate:(NSNotification*)notif {
LinphoneCall *call = [[notif.userInfo objectForKey: @"call"] pointerValue];
LinphoneCallState state = [[notif.userInfo objectForKey: @"state"] intValue];
@ -321,8 +341,11 @@ static PhoneMainView* phoneMainViewInstance=nil;
}
}
- (void)startUp {
if ([[LinphoneManager instance] lpConfigBoolForKey:@"enable_first_login_view_preference"] == true) {
- (void)startUp {
if( linphone_core_get_global_state([LinphoneManager getLc]) != LinphoneGlobalOn ){
[self changeCurrentView: [DialerViewController compositeViewDescription]];
} else if ([[LinphoneManager instance] lpConfigBoolForKey:@"enable_first_login_view_preference"] == true) {
// Change to fist login view
[self changeCurrentView: [FirstLoginViewController compositeViewDescription]];
} else {

View file

@ -21,7 +21,13 @@
#import <XMLRPCConnectionDelegate.h>
#import "UICompositeViewController.h"
@interface WizardViewController : TPMultiLayoutViewController <UITextFieldDelegate, UICompositeViewDelegate, XMLRPCConnectionDelegate, UIGestureRecognizerDelegate> {
@interface WizardViewController : TPMultiLayoutViewController
<UITextFieldDelegate,
UICompositeViewDelegate,
XMLRPCConnectionDelegate,
UIGestureRecognizerDelegate,
UIAlertViewDelegate>
{
@private
UITextField *activeTextField;
UIView *currentView;
@ -44,12 +50,15 @@
@property (nonatomic, retain) IBOutlet UIButton *createAccountButton;
@property (nonatomic, retain) IBOutlet UIButton *connectAccountButton;
@property (nonatomic, retain) IBOutlet UIButton *externalAccountButton;
@property (retain, nonatomic) IBOutlet UIButton *remoteProvisioningButton;
@property (nonatomic, retain) IBOutlet UIImageView *choiceViewLogoImageView;
@property (nonatomic, retain) IBOutlet UITapGestureRecognizer *viewTapGestureRecognizer;
- (void)reset;
- (void)handleRemoteProvisioning;
- (IBAction)onStartClick:(id)sender;
- (IBAction)onBackClick:(id)sender;
@ -59,6 +68,7 @@
- (IBAction)onConnectAccountClick:(id)sender;
- (IBAction)onExternalAccountClick:(id)sender;
- (IBAction)onCheckValidationClick:(id)sender;
- (IBAction)onRemoteProvisioningClick:(id)sender;
- (IBAction)onSignInClick:(id)sender;
- (IBAction)onSignInExternalClick:(id)sender;

View file

@ -27,14 +27,15 @@
#import <XMLRPCRequest.h>
typedef enum _ViewElement {
ViewElement_Username = 100,
ViewElement_Password = 101,
ViewElement_Password2 = 102,
ViewElement_Email = 103,
ViewElement_Domain = 104,
ViewElement_Label = 200,
ViewElement_Error = 201,
ViewElement_Username_Error = 404
ViewElement_Username = 100,
ViewElement_Password = 101,
ViewElement_Password2 = 102,
ViewElement_Email = 103,
ViewElement_Domain = 104,
ViewElement_RemoteProvDetails = 105,
ViewElement_Label = 200,
ViewElement_Error = 201,
ViewElement_Username_Error = 404
} ViewElement;
@implementation WizardViewController
@ -102,6 +103,7 @@ typedef enum _ViewElement {
[viewTapGestureRecognizer release];
[_remoteProvisioningButton release];
[super dealloc];
}
@ -135,7 +137,11 @@ static UICompositeViewDescription *compositeDescription = nil;
selector:@selector(registrationUpdateEvent:)
name:kLinphoneRegistrationUpdate
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(configuringUpdate:)
name:kLinphoneConfiguringStateUpdate
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
@ -149,16 +155,19 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kLinphoneRegistrationUpdate
object:nil];
name:kLinphoneRegistrationUpdate
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kLinphoneConfiguringStateUpdate
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillHideNotification
object:nil];
}
- (void)viewDidLoad {
@ -191,6 +200,38 @@ static UICompositeViewDescription *compositeDescription = nil;
}
}
- (void)handleRemoteProvisioning {
[self resetTextFields];
LinphoneProxyConfig* default_conf = linphone_core_create_proxy_config([LinphoneManager getLc]);
const char* identity = linphone_proxy_config_get_identity(default_conf);
if( identity ){
LinphoneAddress* default_addr = linphone_address_new(identity);
if( default_addr ){
const char* domain = linphone_address_get_domain(default_addr);
if( domain && strlen(domain) > 0){
UITextField* domainfield = [WizardViewController findTextField:ViewElement_Domain view:externalAccountView];
[domainfield setText:[NSString stringWithUTF8String:domain]];
}
}
}
[self changeView:externalAccountView back:FALSE animation:TRUE];
linphone_proxy_config_destroy(default_conf);
}
- (void)resetTextFields {
[WizardViewController cleanTextField:welcomeView];
[WizardViewController cleanTextField:choiceView];
[WizardViewController cleanTextField:createAccountView];
[WizardViewController cleanTextField:connectAccountView];
[WizardViewController cleanTextField:externalAccountView];
[WizardViewController cleanTextField:validateAccountView];
}
- (void)reset {
[self clearProxyConfig];
[[LinphoneManager instance] lpConfigSetBool:FALSE forKey:@"pushnotification_preference"];
@ -210,12 +251,7 @@ static UICompositeViewDescription *compositeDescription = nil;
[[LinphoneManager instance] lpConfigSetString:@"" forKey:@"stun_preference"];
linphone_core_set_stun_server(lc, NULL);
linphone_core_set_firewall_policy(lc, LinphonePolicyNoFirewall);
[WizardViewController cleanTextField:welcomeView];
[WizardViewController cleanTextField:choiceView];
[WizardViewController cleanTextField:createAccountView];
[WizardViewController cleanTextField:connectAccountView];
[WizardViewController cleanTextField:externalAccountView];
[WizardViewController cleanTextField:validateAccountView];
[self resetTextFields];
if ([[LinphoneManager instance] lpConfigBoolForKey:@"hide_wizard_welcome_view_preference"] == true) {
[self changeView:choiceView back:FALSE animation:FALSE];
} else {
@ -286,6 +322,7 @@ static UICompositeViewDescription *compositeDescription = nil;
// [ Create Btn ]
// [ Connect Btn ]
// [ External Btn ]
// [ Remote Prov ]
BOOL show_logo = [[LinphoneManager instance] lpConfigBoolForKey:@"show_wizard_logo_in_choice_view_preference"];
BOOL show_extern = ![[LinphoneManager instance] lpConfigBoolForKey:@"hide_wizard_custom_account"];
@ -437,9 +474,9 @@ static UICompositeViewDescription *compositeDescription = nil;
[self setDefaultSettings:proxyCfg];
}
linphone_proxy_config_enable_register(proxyCfg, true);
linphone_core_add_auth_info([LinphoneManager getLc], info);
linphone_core_add_proxy_config([LinphoneManager getLc], proxyCfg);
linphone_core_set_default_proxy([LinphoneManager getLc], proxyCfg);
linphone_core_add_auth_info([LinphoneManager getLc], info);
}
- (NSString*)identityFromUsername:(NSString*)username {
@ -614,6 +651,23 @@ static UICompositeViewDescription *compositeDescription = nil;
[self checkAccountValidation:identity];
}
- (IBAction)onRemoteProvisioningClick:(id)sender {
UIAlertView* remoteInput = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Enter provisioning URL", @"")
message:@""
delegate:self
cancelButtonTitle:NSLocalizedString(@"Cancel", @"")
otherButtonTitles:NSLocalizedString(@"Fetch", @""), nil];
remoteInput.alertViewStyle = UIAlertViewStylePlainTextInput;
UITextField* prov_url = [remoteInput textFieldAtIndex:0];
prov_url.keyboardType = UIKeyboardTypeURL;
prov_url.text = [[LinphoneManager instance] lpConfigStringForKey:@"config-uri" forSection:@"misc"];
prov_url.placeholder = @"URL";
[remoteInput show];
[remoteInput release];
}
- (IBAction)onSignInExternalClick:(id)sender {
NSString *username = [WizardViewController findTextField:ViewElement_Username view:contentView].text;
NSString *password = [WizardViewController findTextField:ViewElement_Password view:contentView].text;
@ -719,6 +773,55 @@ static UICompositeViewDescription *compositeDescription = nil;
[LinphoneUtils findAndResignFirstResponder:currentView];
}
#pragma mark - UIAlertViewDelegate
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 1) { /* fetch */
NSString* url = [alertView textFieldAtIndex:0].text;
if( [url length] > 0 ){
// missing prefix will result in http:// being used
if( [url rangeOfString:@"://"].location == NSNotFound )
url = [NSString stringWithFormat:@"http://%@", url];
[LinphoneLogger log:LinphoneLoggerLog format:@"Should use remote provisioning URL %@", url];
linphone_core_set_provisioning_uri([LinphoneManager getLc], [url UTF8String]);
[waitView setHidden:false];
[[LinphoneManager instance] resetLinphoneCore];
}
} else {
[LinphoneLogger log:LinphoneLoggerLog format:@"Canceled remote provisioning"];
}
}
- (void)configuringUpdate:(NSNotification *)notif {
LinphoneConfiguringState status = (LinphoneConfiguringState)[[notif.userInfo valueForKey:@"state"] integerValue];
[waitView setHidden:true];
switch (status) {
case LinphoneConfiguringSuccessful:
[self handleRemoteProvisioning];
break;
case LinphoneConfiguringFailed:
{
NSString* error_message = [notif.userInfo valueForKey:@"message"];
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Provisioning Load error", nil)
message:error_message
delegate:nil
cancelButtonTitle:NSLocalizedString(@"OK", nil)
otherButtonTitles: nil];
[alert show];
[alert release];
break;
}
case LinphoneConfiguringSkipped:
default:
break;
}
}
#pragma mark - Event Functions
@ -914,4 +1017,8 @@ static UICompositeViewDescription *compositeDescription = nil;
return YES;
}
- (void)viewDidUnload {
[self setRemoteProvisioningButton:nil];
[super viewDidUnload];
}
@end

View file

@ -302,3 +302,4 @@
"Enter an address" = "Enter SIP address or phone number...";
"%@ is composing..." = "%@ is composing...";
"Resend" = "Resend";
"Fetching remote configuration" = "Fetching remote configuration";

View file

@ -302,3 +302,4 @@
"Enter an address" = "Entrez une addresse SIP ou un numéro de téléphone...";
"%@ is composing..." = "%@ rédige un message...";
"Resend" = "Renvoyer";
"Fetching remote configuration" = "Récupération de la conf. distante";

View file

@ -302,3 +302,4 @@
"Enter an address" = "Введите адрес SIP или номер телефона...";
"%@ is composing..." = "%@ is composing...";
"Resend" = "Resend";
"Fetching remote configuration" = "Fetching remote configuration";