mirror of
https://github.com/moonlight-stream/moonlight-ios.git
synced 2026-06-17 14:11:35 +00:00
starting steam and paring work
This commit is contained in:
@@ -37,6 +37,7 @@
|
|||||||
FB290E7919B37D81004C83CF /* MainFrame-iPad.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FB290E7819B37D81004C83CF /* MainFrame-iPad.storyboard */; };
|
FB290E7919B37D81004C83CF /* MainFrame-iPad.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FB290E7819B37D81004C83CF /* MainFrame-iPad.storyboard */; };
|
||||||
FB290E7B19B38036004C83CF /* MainFrame-iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FB290E7A19B38036004C83CF /* MainFrame-iPhone.storyboard */; };
|
FB290E7B19B38036004C83CF /* MainFrame-iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FB290E7A19B38036004C83CF /* MainFrame-iPhone.storyboard */; };
|
||||||
FB63FCF219F43EBC00227761 /* PairManager.m in Sources */ = {isa = PBXBuildFile; fileRef = FB63FCF119F43EBC00227761 /* PairManager.m */; };
|
FB63FCF219F43EBC00227761 /* PairManager.m in Sources */ = {isa = PBXBuildFile; fileRef = FB63FCF119F43EBC00227761 /* PairManager.m */; };
|
||||||
|
FB63FCF719F573BE00227761 /* StreamManager.m in Sources */ = {isa = PBXBuildFile; fileRef = FB63FCF619F573BE00227761 /* StreamManager.m */; };
|
||||||
FB7E794419C8B71B00A15F68 /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FB7E794319C8B71B00A15F68 /* libiconv.dylib */; };
|
FB7E794419C8B71B00A15F68 /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FB7E794319C8B71B00A15F68 /* libiconv.dylib */; };
|
||||||
FBAB29F219EDB08B00929691 /* MDNSManager.m in Sources */ = {isa = PBXBuildFile; fileRef = FBAB29F119EDB08B00929691 /* MDNSManager.m */; };
|
FBAB29F219EDB08B00929691 /* MDNSManager.m in Sources */ = {isa = PBXBuildFile; fileRef = FBAB29F119EDB08B00929691 /* MDNSManager.m */; };
|
||||||
FBAB29F619EDE0F800929691 /* Computer.m in Sources */ = {isa = PBXBuildFile; fileRef = FBAB29F519EDE0F800929691 /* Computer.m */; };
|
FBAB29F619EDE0F800929691 /* Computer.m in Sources */ = {isa = PBXBuildFile; fileRef = FBAB29F519EDE0F800929691 /* Computer.m */; };
|
||||||
@@ -123,6 +124,8 @@
|
|||||||
FB290E7A19B38036004C83CF /* MainFrame-iPhone.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = "MainFrame-iPhone.storyboard"; sourceTree = SOURCE_ROOT; };
|
FB290E7A19B38036004C83CF /* MainFrame-iPhone.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = "MainFrame-iPhone.storyboard"; sourceTree = SOURCE_ROOT; };
|
||||||
FB63FCF019F43EBC00227761 /* PairManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PairManager.h; sourceTree = "<group>"; };
|
FB63FCF019F43EBC00227761 /* PairManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PairManager.h; sourceTree = "<group>"; };
|
||||||
FB63FCF119F43EBC00227761 /* PairManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PairManager.m; sourceTree = "<group>"; };
|
FB63FCF119F43EBC00227761 /* PairManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PairManager.m; sourceTree = "<group>"; };
|
||||||
|
FB63FCF519F573BE00227761 /* StreamManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StreamManager.h; sourceTree = "<group>"; };
|
||||||
|
FB63FCF619F573BE00227761 /* StreamManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StreamManager.m; sourceTree = "<group>"; };
|
||||||
FB7E794319C8B71B00A15F68 /* libiconv.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libiconv.dylib; path = usr/lib/libiconv.dylib; sourceTree = SDKROOT; };
|
FB7E794319C8B71B00A15F68 /* libiconv.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libiconv.dylib; path = usr/lib/libiconv.dylib; sourceTree = SDKROOT; };
|
||||||
FBAB29F119EDB08B00929691 /* MDNSManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MDNSManager.m; sourceTree = "<group>"; };
|
FBAB29F119EDB08B00929691 /* MDNSManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MDNSManager.m; sourceTree = "<group>"; };
|
||||||
FBAB29F319EDB0C400929691 /* MDNSManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MDNSManager.h; sourceTree = "<group>"; };
|
FBAB29F319EDB0C400929691 /* MDNSManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MDNSManager.h; sourceTree = "<group>"; };
|
||||||
@@ -327,6 +330,8 @@
|
|||||||
FBC8622C19F0BEFB0087327B /* HttpManager.m */,
|
FBC8622C19F0BEFB0087327B /* HttpManager.m */,
|
||||||
984C441619F48D1D0061A500 /* StreamView.h */,
|
984C441619F48D1D0061A500 /* StreamView.h */,
|
||||||
984C441719F48D1D0061A500 /* StreamView.m */,
|
984C441719F48D1D0061A500 /* StreamView.m */,
|
||||||
|
FB63FCF519F573BE00227761 /* StreamManager.h */,
|
||||||
|
FB63FCF619F573BE00227761 /* StreamManager.m */,
|
||||||
);
|
);
|
||||||
path = Limelight;
|
path = Limelight;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -682,6 +687,7 @@
|
|||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
FBAB29FC19EE13AA00929691 /* CryptoManager.m in Sources */,
|
FBAB29FC19EE13AA00929691 /* CryptoManager.m in Sources */,
|
||||||
|
FB63FCF719F573BE00227761 /* StreamManager.m in Sources */,
|
||||||
FB63FCF219F43EBC00227761 /* PairManager.m in Sources */,
|
FB63FCF219F43EBC00227761 /* PairManager.m in Sources */,
|
||||||
98A03B5019F3598400861ACA /* VideoDecoderRenderer.m in Sources */,
|
98A03B5019F3598400861ACA /* VideoDecoderRenderer.m in Sources */,
|
||||||
FBAB29F219EDB08B00929691 /* MDNSManager.m in Sources */,
|
FBAB29F219EDB08B00929691 /* MDNSManager.m in Sources */,
|
||||||
|
|||||||
@@ -26,11 +26,13 @@
|
|||||||
- (int) resolveHost
|
- (int) resolveHost
|
||||||
{
|
{
|
||||||
struct hostent *hostent;
|
struct hostent *hostent;
|
||||||
|
|
||||||
if (inet_addr([self.hostName UTF8String]) != INADDR_NONE)
|
if (inet_addr([self.hostName UTF8String]) != INADDR_NONE)
|
||||||
{
|
{
|
||||||
// Already an IP address
|
// Already an IP address
|
||||||
return inet_addr([self.hostName UTF8String]);
|
int addr = inet_addr([self.hostName UTF8String]);
|
||||||
|
NSLog(@"host address: %d", addr);
|
||||||
|
return addr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -39,7 +41,9 @@
|
|||||||
{
|
{
|
||||||
char* ipstr = inet_ntoa(*(struct in_addr*)hostent->h_addr_list[0]);
|
char* ipstr = inet_ntoa(*(struct in_addr*)hostent->h_addr_list[0]);
|
||||||
NSLog(@"Resolved %@ -> %s", self.hostName, ipstr);
|
NSLog(@"Resolved %@ -> %s", self.hostName, ipstr);
|
||||||
return inet_addr(ipstr);
|
int addr = inet_addr(ipstr);
|
||||||
|
NSLog(@"host address: %d", addr);
|
||||||
|
return addr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
@interface Connection : NSOperation <NSStreamDelegate>
|
@interface Connection : NSOperation <NSStreamDelegate>
|
||||||
|
|
||||||
-(id) initWithHost:(int)ipaddr width:(int)width height:(int)height renderer:(VideoDecoderRenderer*)renderer;
|
-(id) initWithHost:(int)ipaddr key:(NSData*)rikey keyId:(int)rikeyid width:(int)width height:(int)height refreshRate:(int)refreshRate renderer:(VideoDecoderRenderer*)myRenderer;
|
||||||
-(void) main;
|
-(void) main;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ void ClDisplayTransientMessage(char* message)
|
|||||||
NSLog(@"DisplayTransientMessage: %s", message);
|
NSLog(@"DisplayTransientMessage: %s", message);
|
||||||
}
|
}
|
||||||
|
|
||||||
-(id) initWithHost:(int)ipaddr width:(int)width height:(int)height renderer:(VideoDecoderRenderer*)myRenderer
|
-(id) initWithHost:(int)ipaddr key:(NSData*)rikey keyId:(int)rikeyid width:(int)width height:(int)height refreshRate:(int)refreshRate renderer:(VideoDecoderRenderer*)myRenderer
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
host = ipaddr;
|
host = ipaddr;
|
||||||
@@ -221,7 +221,11 @@ void ClDisplayTransientMessage(char* message)
|
|||||||
streamConfig.fps = 60;
|
streamConfig.fps = 60;
|
||||||
streamConfig.bitrate = 5000;
|
streamConfig.bitrate = 5000;
|
||||||
streamConfig.packetSize = 1024;
|
streamConfig.packetSize = 1024;
|
||||||
// FIXME: RI AES members
|
|
||||||
|
memcpy(streamConfig.remoteInputAesKey, [rikey bytes], [rikey length]);
|
||||||
|
memset(streamConfig.remoteInputAesIv, 0, 16);
|
||||||
|
rikeyid = htonl(rikeyid);
|
||||||
|
memcpy(streamConfig.remoteInputAesIv, &rikeyid, sizeof(rikeyid));
|
||||||
|
|
||||||
drCallbacks.setup = DrSetup;
|
drCallbacks.setup = DrSetup;
|
||||||
drCallbacks.start = DrStart;
|
drCallbacks.start = DrStart;
|
||||||
|
|||||||
+51
-22
@@ -18,6 +18,9 @@
|
|||||||
|
|
||||||
@implementation CryptoManager
|
@implementation CryptoManager
|
||||||
static const int SHA1_DIGEST_LENGTH = 20;
|
static const int SHA1_DIGEST_LENGTH = 20;
|
||||||
|
static NSData* key = nil;
|
||||||
|
static NSData* cert = nil;
|
||||||
|
static NSData* p12 = nil;
|
||||||
|
|
||||||
- (NSData*) createAESKeyFromSalt:(NSData*)saltedPIN {
|
- (NSData*) createAESKeyFromSalt:(NSData*)saltedPIN {
|
||||||
return [[self SHA1HashData:saltedPIN] subdataWithRange:NSMakeRange(0, 16)];
|
return [[self SHA1HashData:saltedPIN] subdataWithRange:NSMakeRange(0, 16)];
|
||||||
@@ -142,24 +145,47 @@ static const int SHA1_DIGEST_LENGTH = 20;
|
|||||||
|
|
||||||
// TODO: these three methods are almost identical, fix the copy-pasta
|
// TODO: these three methods are almost identical, fix the copy-pasta
|
||||||
+ (NSData*) readCertFromFile {
|
+ (NSData*) readCertFromFile {
|
||||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
if (cert == nil) {
|
||||||
NSString *documentsDirectory = [paths objectAtIndex:0];
|
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||||
NSString *certFile = [documentsDirectory stringByAppendingPathComponent:@"client.crt"];
|
NSString *documentsDirectory = [paths objectAtIndex:0];
|
||||||
return [NSData dataWithContentsOfFile:certFile];
|
NSString *certFile = [documentsDirectory stringByAppendingPathComponent:@"client.crt"];
|
||||||
|
cert = [NSData dataWithContentsOfFile:certFile];
|
||||||
|
}
|
||||||
|
return cert;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSData*) readP12FromFile {
|
+ (NSData*) readP12FromFile {
|
||||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
if (p12 == nil) {
|
||||||
NSString *documentsDirectory = [paths objectAtIndex:0];
|
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||||
NSString *p12File = [documentsDirectory stringByAppendingPathComponent:@"client.p12"];
|
NSString *documentsDirectory = [paths objectAtIndex:0];
|
||||||
return [NSData dataWithContentsOfFile:p12File];
|
NSString *p12File = [documentsDirectory stringByAppendingPathComponent:@"client.p12"];
|
||||||
|
p12 = [NSData dataWithContentsOfFile:p12File];
|
||||||
|
}
|
||||||
|
return p12;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSData*) readKeyFromFile {
|
+ (NSData*) readKeyFromFile {
|
||||||
|
if (key == nil) {
|
||||||
|
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||||
|
NSString *documentsDirectory = [paths objectAtIndex:0];
|
||||||
|
NSString *keyFile = [documentsDirectory stringByAppendingPathComponent:@"client.key"];
|
||||||
|
key = [NSData dataWithContentsOfFile:keyFile];
|
||||||
|
}
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (bool) keyPairExists {
|
||||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||||
NSString *documentsDirectory = [paths objectAtIndex:0];
|
NSString *documentsDirectory = [paths objectAtIndex:0];
|
||||||
NSString *keyFile = [documentsDirectory stringByAppendingPathComponent:@"client.key"];
|
NSString *keyFile = [documentsDirectory stringByAppendingPathComponent:@"client.key"];
|
||||||
return [NSData dataWithContentsOfFile:keyFile];
|
NSString *p12File = [documentsDirectory stringByAppendingPathComponent:@"client.p12"];
|
||||||
|
NSString *certFile = [documentsDirectory stringByAppendingPathComponent:@"client.crt"];
|
||||||
|
|
||||||
|
bool keyFileExists = [[NSFileManager defaultManager] fileExistsAtPath:keyFile];
|
||||||
|
bool p12FileExists = [[NSFileManager defaultManager] fileExistsAtPath:p12File];
|
||||||
|
bool certFileExists = [[NSFileManager defaultManager] fileExistsAtPath:certFile];
|
||||||
|
|
||||||
|
return keyFileExists && p12FileExists && certFileExists;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSData *)getSignatureFromCert:(NSData *)cert {
|
+ (NSData *)getSignatureFromCert:(NSData *)cert {
|
||||||
@@ -177,18 +203,21 @@ static const int SHA1_DIGEST_LENGTH = 20;
|
|||||||
}
|
}
|
||||||
|
|
||||||
+ (void) generateKeyPairUsingSSl {
|
+ (void) generateKeyPairUsingSSl {
|
||||||
NSLog(@"Generating Certificate... ");
|
if (![CryptoManager keyPairExists]) {
|
||||||
CertKeyPair certKeyPair = generateCertKeyPair();
|
|
||||||
|
NSLog(@"Generating Certificate... ");
|
||||||
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
CertKeyPair certKeyPair = generateCertKeyPair();
|
||||||
NSString* documentsDirectory = [paths objectAtIndex:0];
|
|
||||||
NSString* certFile = [documentsDirectory stringByAppendingPathComponent:@"client.crt"];
|
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||||
NSString* keyPairFile = [documentsDirectory stringByAppendingPathComponent:@"client.key"];
|
NSString* documentsDirectory = [paths objectAtIndex:0];
|
||||||
NSString* p12File = [documentsDirectory stringByAppendingPathComponent:@"client.p12"];
|
NSString* certFile = [documentsDirectory stringByAppendingPathComponent:@"client.crt"];
|
||||||
|
NSString* keyPairFile = [documentsDirectory stringByAppendingPathComponent:@"client.key"];
|
||||||
//NSLog(@"Writing cert and key to: \n%@\n%@", certFile, keyPairFile);
|
NSString* p12File = [documentsDirectory stringByAppendingPathComponent:@"client.p12"];
|
||||||
saveCertKeyPair([certFile UTF8String], [p12File UTF8String], [keyPairFile UTF8String], certKeyPair);
|
|
||||||
freeCertKeyPair(certKeyPair);
|
//NSLog(@"Writing cert and key to: \n%@\n%@", certFile, keyPairFile);
|
||||||
|
saveCertKeyPair([certFile UTF8String], [p12File UTF8String], [keyPairFile UTF8String], certKeyPair);
|
||||||
|
freeCertKeyPair(certKeyPair);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSString*) getUniqueID {
|
+ (NSString*) getUniqueID {
|
||||||
@@ -200,7 +229,7 @@ static const int SHA1_DIGEST_LENGTH = 20;
|
|||||||
// and remove the '-' to get a 16 character string
|
// and remove the '-' to get a 16 character string
|
||||||
NSMutableString* uniqueId = [NSMutableString stringWithString:[idString substringFromIndex:19]];
|
NSMutableString* uniqueId = [NSMutableString stringWithString:[idString substringFromIndex:19]];
|
||||||
[uniqueId deleteCharactersInRange:NSMakeRange(4, 1)];
|
[uniqueId deleteCharactersInRange:NSMakeRange(4, 1)];
|
||||||
|
|
||||||
//NSLog(@"Unique ID: %@", uniqueId);
|
//NSLog(@"Unique ID: %@", uniqueId);
|
||||||
return [NSString stringWithString:uniqueId];
|
return [NSString stringWithString:uniqueId];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
- (NSURLRequest*) newPairChallenge;
|
- (NSURLRequest*) newPairChallenge;
|
||||||
- (NSURLRequest*) newAppListRequest;
|
- (NSURLRequest*) newAppListRequest;
|
||||||
- (NSURLRequest*) newServerInfoRequest;
|
- (NSURLRequest*) newServerInfoRequest;
|
||||||
|
- (NSURLRequest*) newLaunchRequest:(NSString*)appId width:(int)width height:(int)height refreshRate:(int)refreshRate rikey:(NSString*)rikey rikeyid:(int)rikeyid;
|
||||||
- (NSData*) executeRequestSynchronously:(NSURLRequest*)request;
|
- (NSData*) executeRequestSynchronously:(NSURLRequest*)request;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|||||||
@@ -150,6 +150,11 @@ static const NSString* PORT = @"47984";
|
|||||||
return [self createRequestFromString:urlString];
|
return [self createRequestFromString:urlString];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSURLRequest*) newLaunchRequest:(NSString*)appId width:(int)width height:(int)height refreshRate:(int)refreshRate rikey:(NSString*)rikey rikeyid:(int)rikeyid {
|
||||||
|
NSString* urlString = [NSString stringWithFormat:@"%@/launch?uniqueid=%@&appid=%@&mode=%dx%dx%d&additionalStates=1&sops=1&rikey=%@&rikeyid=%d", _baseURL, _uniqueId, appId, width, height, refreshRate, rikey, rikeyid];
|
||||||
|
return [self createRequestFromString:urlString];
|
||||||
|
}
|
||||||
|
|
||||||
- (NSString*) bytesToHex:(NSData*)data {
|
- (NSString*) bytesToHex:(NSData*)data {
|
||||||
const unsigned char* bytes = [data bytes];
|
const unsigned char* bytes = [data bytes];
|
||||||
NSMutableString *hex = [[NSMutableString alloc] init];
|
NSMutableString *hex = [[NSMutableString alloc] init];
|
||||||
|
|||||||
@@ -8,8 +8,9 @@
|
|||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
#import "MDNSManager.h"
|
#import "MDNSManager.h"
|
||||||
|
#import "PairManager.h"
|
||||||
|
|
||||||
@interface MainFrameViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate, MDNSCallback, NSURLConnectionDelegate>
|
@interface MainFrameViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate, MDNSCallback, NSURLConnectionDelegate, PairCallback>
|
||||||
@property (strong, nonatomic) IBOutlet UIPickerView *HostPicker;
|
@property (strong, nonatomic) IBOutlet UIPickerView *HostPicker;
|
||||||
- (IBAction)StreamButton:(UIButton *)sender;
|
- (IBAction)StreamButton:(UIButton *)sender;
|
||||||
- (IBAction)PairButton:(UIButton *)sender;
|
- (IBAction)PairButton:(UIButton *)sender;
|
||||||
@@ -18,7 +19,10 @@
|
|||||||
@property (strong, nonatomic) NSArray* streamConfigVals;
|
@property (strong, nonatomic) NSArray* streamConfigVals;
|
||||||
@property (strong, nonatomic) NSArray* hostPickerVals;
|
@property (strong, nonatomic) NSArray* hostPickerVals;
|
||||||
|
|
||||||
- (int) getHostAddr;
|
+ (int) getResolvedHost;
|
||||||
|
+ (NSData*) getRiKey;
|
||||||
|
+ (int) getRiKeyId;
|
||||||
|
|
||||||
- (void) segueIntoStream;
|
- (void) segueIntoStream;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -11,18 +11,31 @@
|
|||||||
#import "Computer.h"
|
#import "Computer.h"
|
||||||
#import "CryptoManager.h"
|
#import "CryptoManager.h"
|
||||||
#import "HttpManager.h"
|
#import "HttpManager.h"
|
||||||
#import "PairManager.h"
|
|
||||||
#import "Connection.h"
|
#import "Connection.h"
|
||||||
#import "VideoDecoderRenderer.h"
|
#import "VideoDecoderRenderer.h"
|
||||||
|
#import "StreamManager.h"
|
||||||
|
|
||||||
@implementation MainFrameViewController {
|
@implementation MainFrameViewController {
|
||||||
NSOperationQueue* _opQueue;
|
NSOperationQueue* _opQueue;
|
||||||
MDNSManager* _mDNSManager;
|
MDNSManager* _mDNSManager;
|
||||||
Computer* _selectedHost;
|
Computer* _selectedHost;
|
||||||
|
UIAlertView* _pairAlert;
|
||||||
|
StreamManager* _streamMan;
|
||||||
|
}
|
||||||
|
static int resolvedHost;
|
||||||
|
static NSData* riKey;
|
||||||
|
static int riKeyId;
|
||||||
|
|
||||||
|
+ (int) getResolvedHost {
|
||||||
|
return resolvedHost;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (int)getHostAddr {
|
+ (NSData*) getRiKey {
|
||||||
return [_selectedHost resolveHost];
|
return riKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (int) getRiKeyId {
|
||||||
|
return riKeyId;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)PairButton:(UIButton *)sender
|
- (void)PairButton:(UIButton *)sender
|
||||||
@@ -33,18 +46,45 @@
|
|||||||
NSData* cert = [CryptoManager readCertFromFile];
|
NSData* cert = [CryptoManager readCertFromFile];
|
||||||
|
|
||||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:_selectedHost.hostName uniqueId:uniqueId deviceName:@"roth" cert:cert];
|
HttpManager* hMan = [[HttpManager alloc] initWithHost:_selectedHost.hostName uniqueId:uniqueId deviceName:@"roth" cert:cert];
|
||||||
PairManager* pMan = [[PairManager alloc] initWithManager:hMan andCert:cert];
|
PairManager* pMan = [[PairManager alloc] initWithManager:hMan andCert:cert callback:self];
|
||||||
|
|
||||||
[_opQueue addOperation:pMan];
|
[_opQueue addOperation:pMan];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)showPIN:(NSString *)PIN {
|
||||||
|
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||||
|
_pairAlert = [[UIAlertView alloc] initWithTitle:@"Pairing" message:[NSString stringWithFormat:@"Enter the following PIN on the host machine: %@", PIN]delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
|
||||||
|
[_pairAlert show];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)pairFailed:(NSString *)message {
|
||||||
|
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||||
|
[_pairAlert dismissWithClickedButtonIndex:0 animated:NO];
|
||||||
|
_pairAlert = [[UIAlertView alloc] initWithTitle:@"Pairing Failed" message:message delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
|
||||||
|
[_pairAlert show];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)pairSuccessful {
|
||||||
|
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||||
|
[_pairAlert dismissWithClickedButtonIndex:0 animated:NO];
|
||||||
|
_pairAlert = [[UIAlertView alloc] initWithTitle:@"Pairing Succesful" message:@"Successfully paired to host" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
|
||||||
|
[_pairAlert show];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
- (void)StreamButton:(UIButton *)sender
|
- (void)StreamButton:(UIButton *)sender
|
||||||
{
|
{
|
||||||
NSLog(@"Stream Button Pressed!");
|
NSLog(@"Stream Button Pressed!");
|
||||||
[self segueIntoStream];
|
_streamMan = [[StreamManager alloc] initWithHost:_selectedHost.hostName andViewController:self];
|
||||||
|
[_opQueue addOperation:_streamMan];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) segueIntoStream {
|
- (void) segueIntoStream {
|
||||||
|
resolvedHost = [_selectedHost resolveHost];
|
||||||
|
riKey = [_streamMan getRiKey];
|
||||||
|
riKeyId = [_streamMan getRiKeyId];
|
||||||
[self performSegueWithIdentifier:@"createStreamFrame" sender:self];
|
[self performSegueWithIdentifier:@"createStreamFrame" sender:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+13
-1
@@ -9,9 +9,21 @@
|
|||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import "HttpManager.h"
|
#import "HttpManager.h"
|
||||||
|
|
||||||
|
@protocol PairCallback <NSObject>
|
||||||
|
|
||||||
|
- (void) showPIN:(NSString*)PIN;
|
||||||
|
- (void) pairSuccessful;
|
||||||
|
- (void) pairFailed:(NSString*)message;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
@interface PairManager : NSOperation
|
@interface PairManager : NSOperation
|
||||||
- (id) initWithManager:(HttpManager*)httpManager andCert:(NSData*)cert;
|
- (id) initWithManager:(HttpManager*)httpManager andCert:(NSData*)cert callback:(id<PairCallback>)callback;
|
||||||
- (NSString*) generatePIN;
|
- (NSString*) generatePIN;
|
||||||
- (NSData*) saltPIN:(NSString*)PIN;
|
- (NSData*) saltPIN:(NSString*)PIN;
|
||||||
- (void) initiatePair;
|
- (void) initiatePair;
|
||||||
|
|
||||||
|
+ (NSData*) randomBytes:(NSInteger)length;
|
||||||
|
+ (NSString*) bytesToHex:(NSData*)data;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
+32
-8
@@ -14,27 +14,38 @@
|
|||||||
@implementation PairManager {
|
@implementation PairManager {
|
||||||
HttpManager* _httpManager;
|
HttpManager* _httpManager;
|
||||||
NSData* _cert;
|
NSData* _cert;
|
||||||
|
id<PairCallback> _callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) initWithManager:(HttpManager*)httpManager andCert:(NSData*)cert {
|
- (id) initWithManager:(HttpManager*)httpManager andCert:(NSData*)cert callback:(id<PairCallback>)callback {
|
||||||
self = [super init];
|
self = [super init];
|
||||||
_httpManager = httpManager;
|
_httpManager = httpManager;
|
||||||
_cert = cert;
|
_cert = cert;
|
||||||
|
_callback = callback;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) main {
|
- (void) main {
|
||||||
[self initiatePair];
|
NSData* serverInfo = [_httpManager executeRequestSynchronously:[_httpManager newServerInfoRequest]];
|
||||||
|
if (![[HttpManager getStringFromXML:serverInfo tag:@"PairStatus"] isEqual:@"1"]) {
|
||||||
|
[self initiatePair];
|
||||||
|
} else {
|
||||||
|
[_callback pairFailed:@"Already Paired"];
|
||||||
|
}
|
||||||
|
[_httpManager executeRequestSynchronously:[_httpManager newAppListRequest]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) initiatePair {
|
- (void) initiatePair {
|
||||||
NSString* PIN = [self generatePIN];
|
NSString* PIN = [self generatePIN];
|
||||||
NSData* salt = [self saltPIN:PIN];
|
NSData* salt = [self saltPIN:PIN];
|
||||||
NSLog(@"PIN: %@, saltedPIN: %@", PIN, salt);
|
NSLog(@"PIN: %@, saltedPIN: %@", PIN, salt);
|
||||||
|
[_callback showPIN:PIN];
|
||||||
|
|
||||||
NSData* pairResp = [_httpManager executeRequestSynchronously:[_httpManager newPairRequest:salt]];
|
NSData* pairResp = [_httpManager executeRequestSynchronously:[_httpManager newPairRequest:salt]];
|
||||||
if ([[HttpManager getStringFromXML:pairResp tag:@"paired"] intValue] != 1) {
|
if ([[HttpManager getStringFromXML:pairResp tag:@"paired"] intValue] != 1) {
|
||||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||||
|
//TODO: better message
|
||||||
|
[_callback pairFailed:@"pairResp failed"];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,12 +54,14 @@
|
|||||||
CryptoManager* cryptoMan = [[CryptoManager alloc] init];
|
CryptoManager* cryptoMan = [[CryptoManager alloc] init];
|
||||||
NSData* aesKey = [cryptoMan createAESKeyFromSalt:salt];
|
NSData* aesKey = [cryptoMan createAESKeyFromSalt:salt];
|
||||||
|
|
||||||
NSData* randomChallenge = [self randomBytes:16];
|
NSData* randomChallenge = [PairManager randomBytes:16];
|
||||||
NSData* encryptedChallenge = [cryptoMan aesEncrypt:randomChallenge withKey:aesKey];
|
NSData* encryptedChallenge = [cryptoMan aesEncrypt:randomChallenge withKey:aesKey];
|
||||||
|
|
||||||
NSData* challengeResp = [_httpManager executeRequestSynchronously:[_httpManager newChallengeRequest:encryptedChallenge]];
|
NSData* challengeResp = [_httpManager executeRequestSynchronously:[_httpManager newChallengeRequest:encryptedChallenge]];
|
||||||
if ([[HttpManager getStringFromXML:challengeResp tag:@"paired"] intValue] != 1) {
|
if ([[HttpManager getStringFromXML:challengeResp tag:@"paired"] intValue] != 1) {
|
||||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||||
|
//TODO: better message
|
||||||
|
[_callback pairFailed:@"challengeResp failed"];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,13 +71,15 @@
|
|||||||
NSData* serverResponse = [decServerChallengeResp subdataWithRange:NSMakeRange(0, 20)];
|
NSData* serverResponse = [decServerChallengeResp subdataWithRange:NSMakeRange(0, 20)];
|
||||||
NSData* serverChallenge = [decServerChallengeResp subdataWithRange:NSMakeRange(20, 16)];
|
NSData* serverChallenge = [decServerChallengeResp subdataWithRange:NSMakeRange(20, 16)];
|
||||||
|
|
||||||
NSData* clientSecret = [self randomBytes:16];
|
NSData* clientSecret = [PairManager randomBytes:16];
|
||||||
NSData* challengeRespHash = [cryptoMan SHA1HashData:[self concatData:[self concatData:serverChallenge with:[CryptoManager getSignatureFromCert:_cert]] with:clientSecret]];
|
NSData* challengeRespHash = [cryptoMan SHA1HashData:[self concatData:[self concatData:serverChallenge with:[CryptoManager getSignatureFromCert:_cert]] with:clientSecret]];
|
||||||
NSData* challengeRespEncrypted = [cryptoMan aesEncrypt:challengeRespHash withKey:aesKey];
|
NSData* challengeRespEncrypted = [cryptoMan aesEncrypt:challengeRespHash withKey:aesKey];
|
||||||
|
|
||||||
NSData* secretResp = [_httpManager executeRequestSynchronously:[_httpManager newChallengeRespRequest:challengeRespEncrypted]];
|
NSData* secretResp = [_httpManager executeRequestSynchronously:[_httpManager newChallengeRespRequest:challengeRespEncrypted]];
|
||||||
if ([[HttpManager getStringFromXML:secretResp tag:@"paired"] intValue] != 1) {
|
if ([[HttpManager getStringFromXML:secretResp tag:@"paired"] intValue] != 1) {
|
||||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||||
|
//TODO: better message
|
||||||
|
[_callback pairFailed:@"secretResp failed"];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,27 +89,36 @@
|
|||||||
|
|
||||||
if (![cryptoMan verifySignature:serverSecret withSignature:serverSignature andCert:[self hexToBytes:plainCert]]) {
|
if (![cryptoMan verifySignature:serverSecret withSignature:serverSignature andCert:[self hexToBytes:plainCert]]) {
|
||||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||||
|
//TODO: better message
|
||||||
|
[_callback pairFailed:@"verifySignature failed"];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSData* serverChallengeRespHash = [cryptoMan SHA1HashData:[self concatData:[self concatData:randomChallenge with:[CryptoManager getSignatureFromCert:[self hexToBytes:plainCert]]] with:serverSecret]];
|
NSData* serverChallengeRespHash = [cryptoMan SHA1HashData:[self concatData:[self concatData:randomChallenge with:[CryptoManager getSignatureFromCert:[self hexToBytes:plainCert]]] with:serverSecret]];
|
||||||
if (![serverChallengeRespHash isEqual:serverResponse]) {
|
if (![serverChallengeRespHash isEqual:serverResponse]) {
|
||||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||||
|
//TODO: better message
|
||||||
|
[_callback pairFailed:@"serverChallengeResp failed"];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSData* clientPairingSecret = [self concatData:clientSecret with:[cryptoMan signData:clientSecret withKey:[CryptoManager readKeyFromFile]]];
|
NSData* clientPairingSecret = [self concatData:clientSecret with:[cryptoMan signData:clientSecret withKey:[CryptoManager readKeyFromFile]]];
|
||||||
NSData* clientSecretResp = [_httpManager executeRequestSynchronously:[_httpManager newClientSecretRespRequest:[self bytesToHex:clientPairingSecret]]];
|
NSData* clientSecretResp = [_httpManager executeRequestSynchronously:[_httpManager newClientSecretRespRequest:[PairManager bytesToHex:clientPairingSecret]]];
|
||||||
if (![[HttpManager getStringFromXML:clientSecretResp tag:@"paired"] isEqual:@"1"]) {
|
if (![[HttpManager getStringFromXML:clientSecretResp tag:@"paired"] isEqual:@"1"]) {
|
||||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||||
|
//TODO: better message
|
||||||
|
[_callback pairFailed:@"clientSecretResp failed"];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSData* clientPairChallenge = [_httpManager executeRequestSynchronously:[_httpManager newPairChallenge]];
|
NSData* clientPairChallenge = [_httpManager executeRequestSynchronously:[_httpManager newPairChallenge]];
|
||||||
if (![[HttpManager getStringFromXML:clientPairChallenge tag:@"paired"] isEqual:@"1"]) {
|
if (![[HttpManager getStringFromXML:clientPairChallenge tag:@"paired"] isEqual:@"1"]) {
|
||||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||||
|
//TODO: better message
|
||||||
|
[_callback pairFailed:@"clientPairChallenge failed"];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
[_callback pairSuccessful];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSData*) concatData:(NSData*)data with:(NSData*)moreData {
|
- (NSData*) concatData:(NSData*)data with:(NSData*)moreData {
|
||||||
@@ -113,14 +137,14 @@
|
|||||||
|
|
||||||
- (NSData*) saltPIN:(NSString*)PIN {
|
- (NSData*) saltPIN:(NSString*)PIN {
|
||||||
NSMutableData* saltedPIN = [[NSMutableData alloc] initWithCapacity:20];
|
NSMutableData* saltedPIN = [[NSMutableData alloc] initWithCapacity:20];
|
||||||
[saltedPIN appendData:[self randomBytes:16]];
|
[saltedPIN appendData:[PairManager randomBytes:16]];
|
||||||
[saltedPIN appendBytes:[PIN UTF8String] length:4];
|
[saltedPIN appendBytes:[PIN UTF8String] length:4];
|
||||||
|
|
||||||
//NSLog(@"Salted PIN: %@", [saltedPIN description]);
|
//NSLog(@"Salted PIN: %@", [saltedPIN description]);
|
||||||
return saltedPIN;
|
return saltedPIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSData*) randomBytes:(NSInteger)length {
|
+ (NSData*) randomBytes:(NSInteger)length {
|
||||||
char* bytes = malloc(length);
|
char* bytes = malloc(length);
|
||||||
arc4random_buf(bytes, length);
|
arc4random_buf(bytes, length);
|
||||||
NSData* randomData = [NSData dataWithBytes:bytes length:length];
|
NSData* randomData = [NSData dataWithBytes:bytes length:length];
|
||||||
@@ -146,7 +170,7 @@
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString*) bytesToHex:(NSData*)data {
|
+ (NSString*) bytesToHex:(NSData*)data {
|
||||||
const unsigned char* bytes = [data bytes];
|
const unsigned char* bytes = [data bytes];
|
||||||
NSMutableString *hex = [[NSMutableString alloc] init];
|
NSMutableString *hex = [[NSMutableString alloc] init];
|
||||||
for (int i = 0; i < [data length]; i++) {
|
for (int i = 0; i < [data length]; i++) {
|
||||||
|
|||||||
@@ -16,28 +16,17 @@
|
|||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
@interface StreamFrameViewController ()
|
@implementation StreamFrameViewController
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation StreamFrameViewController {
|
|
||||||
int _host;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
|
|
||||||
_host = [sender getHostAddr];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)viewDidLoad
|
- (void)viewDidLoad
|
||||||
{
|
{
|
||||||
[super viewDidLoad];
|
[super viewDidLoad];
|
||||||
|
|
||||||
[UIApplication sharedApplication].idleTimerDisabled = YES;
|
[UIApplication sharedApplication].idleTimerDisabled = YES;
|
||||||
|
|
||||||
VideoDecoderRenderer* renderer = [[VideoDecoderRenderer alloc]initWithView:self.view];
|
VideoDecoderRenderer* renderer = [[VideoDecoderRenderer alloc]initWithView:self.view];
|
||||||
|
|
||||||
Connection* conn = [[Connection alloc] initWithHost:_host width:1280 height:720
|
Connection* conn = [[Connection alloc] initWithHost:[MainFrameViewController getResolvedHost] key:[MainFrameViewController getRiKey] keyId:[MainFrameViewController getRiKeyId] width:1280 height:720 refreshRate:60 renderer:renderer];
|
||||||
renderer: renderer];
|
|
||||||
|
|
||||||
NSOperationQueue* opQueue = [[NSOperationQueue alloc] init];
|
NSOperationQueue* opQueue = [[NSOperationQueue alloc] init];
|
||||||
[opQueue addOperation:conn];
|
[opQueue addOperation:conn];
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// StreamManager.h
|
||||||
|
// Limelight
|
||||||
|
//
|
||||||
|
// Created by Diego Waxemberg on 10/20/14.
|
||||||
|
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import "MainFrameViewController.h"
|
||||||
|
|
||||||
|
@interface StreamManager : NSOperation
|
||||||
|
|
||||||
|
- (id) initWithHost:(NSString*)host andViewController:(MainFrameViewController*)viewCont;
|
||||||
|
- (NSData*) getRiKey;
|
||||||
|
- (int) getRiKeyId;
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
//
|
||||||
|
// StreamManager.m
|
||||||
|
// Limelight
|
||||||
|
//
|
||||||
|
// Created by Diego Waxemberg on 10/20/14.
|
||||||
|
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "StreamManager.h"
|
||||||
|
#import "CryptoManager.h"
|
||||||
|
#import "HttpManager.h"
|
||||||
|
#import "PairManager.h"
|
||||||
|
|
||||||
|
@implementation StreamManager {
|
||||||
|
MainFrameViewController* _viewCont;
|
||||||
|
NSString* _host;
|
||||||
|
NSData* _riKey;
|
||||||
|
int _riKeyId;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id) initWithHost:(NSString*)host andViewController:(MainFrameViewController *)viewCont {
|
||||||
|
self = [super init];
|
||||||
|
_host = host;
|
||||||
|
_viewCont = viewCont;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSData*) getRiKey {
|
||||||
|
return _riKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (int) getRiKeyId {
|
||||||
|
return _riKeyId;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)main {
|
||||||
|
[CryptoManager generateKeyPairUsingSSl];
|
||||||
|
NSString* uniqueId = [CryptoManager getUniqueID];
|
||||||
|
NSData* cert = [CryptoManager readCertFromFile];
|
||||||
|
|
||||||
|
HttpManager* hMan = [[HttpManager alloc] initWithHost:_host uniqueId:uniqueId deviceName:@"roth" cert:cert];
|
||||||
|
_riKey = [PairManager randomBytes:16];
|
||||||
|
_riKeyId = arc4random();
|
||||||
|
|
||||||
|
NSData* launchResp = [hMan executeRequestSynchronously:[hMan newLaunchRequest:@"67339056" width:1280 height:720 refreshRate:60 rikey:[PairManager bytesToHex:_riKey] rikeyid:_riKeyId]];
|
||||||
|
[HttpManager getStringFromXML:launchResp tag:@"gamesession"];
|
||||||
|
[_viewCont segueIntoStream];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
Reference in New Issue
Block a user