fixed a lot of jank. created a utils file and removed unused files

This commit is contained in:
Diego Waxemberg
2014-10-20 19:20:50 -04:00
parent 283a386b9c
commit 37428c8c77
21 changed files with 209 additions and 516 deletions

View File

@@ -27,7 +27,6 @@
FB290D1B19B2C406004C83CF /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = FB290D1919B2C406004C83CF /* InfoPlist.strings */; };
FB290D1D19B2C406004C83CF /* LimelightTests.m in Sources */ = {isa = PBXBuildFile; fileRef = FB290D1C19B2C406004C83CF /* LimelightTests.m */; };
FB290D3719B2C6E3004C83CF /* Connection.m in Sources */ = {isa = PBXBuildFile; fileRef = FB290D2719B2C6E3004C83CF /* Connection.m */; };
FB290D3819B2C6E3004C83CF /* ConnectionHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = FB290D2919B2C6E3004C83CF /* ConnectionHandler.m */; };
FB290D3919B2C6E3004C83CF /* MainFrameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FB290D2B19B2C6E3004C83CF /* MainFrameViewController.m */; };
FB290D3A19B2C6E3004C83CF /* StreamFrameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FB290D2D19B2C6E3004C83CF /* StreamFrameViewController.m */; };
FB290DB719B2C870004C83CF /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FB290DB619B2C870004C83CF /* libz.dylib */; };
@@ -39,6 +38,8 @@
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 */; };
FB8945EF19F5C3CD00339C8A /* Utils.m in Sources */ = {isa = PBXBuildFile; fileRef = FB8945EE19F5C3CD00339C8A /* Utils.m */; };
FB8945F219F5C76C00339C8A /* StreamConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = FB8945F119F5C76C00339C8A /* StreamConfiguration.m */; };
FBAB29F219EDB08B00929691 /* MDNSManager.m in Sources */ = {isa = PBXBuildFile; fileRef = FBAB29F119EDB08B00929691 /* MDNSManager.m */; };
FBAB29F619EDE0F800929691 /* Computer.m in Sources */ = {isa = PBXBuildFile; fileRef = FBAB29F519EDE0F800929691 /* Computer.m */; };
FBAB29FC19EE13AA00929691 /* CryptoManager.m in Sources */ = {isa = PBXBuildFile; fileRef = FBAB29FB19EE13AA00929691 /* CryptoManager.m */; };
@@ -104,8 +105,6 @@
FB290D1C19B2C406004C83CF /* LimelightTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LimelightTests.m; sourceTree = "<group>"; };
FB290D2619B2C6E3004C83CF /* Connection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Connection.h; sourceTree = "<group>"; };
FB290D2719B2C6E3004C83CF /* Connection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Connection.m; sourceTree = "<group>"; };
FB290D2819B2C6E3004C83CF /* ConnectionHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConnectionHandler.h; sourceTree = "<group>"; };
FB290D2919B2C6E3004C83CF /* ConnectionHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ConnectionHandler.m; sourceTree = "<group>"; };
FB290D2A19B2C6E3004C83CF /* MainFrameViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainFrameViewController.h; sourceTree = "<group>"; };
FB290D2B19B2C6E3004C83CF /* MainFrameViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainFrameViewController.m; sourceTree = "<group>"; };
FB290D2C19B2C6E3004C83CF /* StreamFrameViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StreamFrameViewController.h; sourceTree = "<group>"; };
@@ -127,6 +126,10 @@
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; };
FB8945ED19F5C3CD00339C8A /* Utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Utils.h; sourceTree = "<group>"; };
FB8945EE19F5C3CD00339C8A /* Utils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Utils.m; sourceTree = "<group>"; };
FB8945F019F5C76C00339C8A /* StreamConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StreamConfiguration.h; sourceTree = "<group>"; };
FB8945F119F5C76C00339C8A /* StreamConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StreamConfiguration.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>"; };
FBAB29F419EDE0F800929691 /* Computer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Computer.h; sourceTree = "<group>"; };
@@ -305,8 +308,6 @@
FB290D3019B2C6E3004C83CF /* Video */,
FB290D2619B2C6E3004C83CF /* Connection.h */,
FB290D2719B2C6E3004C83CF /* Connection.m */,
FB290D2819B2C6E3004C83CF /* ConnectionHandler.h */,
FB290D2919B2C6E3004C83CF /* ConnectionHandler.m */,
FB290D2A19B2C6E3004C83CF /* MainFrameViewController.h */,
FB290D2B19B2C6E3004C83CF /* MainFrameViewController.m */,
FB290D2C19B2C6E3004C83CF /* StreamFrameViewController.h */,
@@ -332,6 +333,10 @@
984C441719F48D1D0061A500 /* StreamView.m */,
FB63FCF519F573BE00227761 /* StreamManager.h */,
FB63FCF619F573BE00227761 /* StreamManager.m */,
FB8945ED19F5C3CD00339C8A /* Utils.h */,
FB8945EE19F5C3CD00339C8A /* Utils.m */,
FB8945F019F5C76C00339C8A /* StreamConfiguration.h */,
FB8945F119F5C76C00339C8A /* StreamConfiguration.m */,
);
path = Limelight;
sourceTree = "<group>";
@@ -609,6 +614,9 @@
LastUpgradeCheck = 0510;
ORGANIZATIONNAME = "Limelight Stream";
TargetAttributes = {
FB290CED19B2C406004C83CF = {
DevelopmentTeam = DM46QST4M7;
};
FB290D0D19B2C406004C83CF = {
TestTargetID = FB290CED19B2C406004C83CF;
};
@@ -689,6 +697,7 @@
FBAB29FC19EE13AA00929691 /* CryptoManager.m in Sources */,
FB63FCF719F573BE00227761 /* StreamManager.m in Sources */,
FB63FCF219F43EBC00227761 /* PairManager.m in Sources */,
FB8945EF19F5C3CD00339C8A /* Utils.m in Sources */,
98A03B5019F3598400861ACA /* VideoDecoderRenderer.m in Sources */,
FBAB29F219EDB08B00929691 /* MDNSManager.m in Sources */,
FBC8622D19F0BEFB0087327B /* HttpManager.m in Sources */,
@@ -697,11 +706,11 @@
FBAB29F619EDE0F800929691 /* Computer.m in Sources */,
FB290D3A19B2C6E3004C83CF /* StreamFrameViewController.m in Sources */,
FB290D0019B2C406004C83CF /* main.m in Sources */,
FB8945F219F5C76C00339C8A /* StreamConfiguration.m in Sources */,
FB290D3919B2C6E3004C83CF /* MainFrameViewController.m in Sources */,
984C441819F48D1D0061A500 /* StreamView.m in Sources */,
FB290D3719B2C6E3004C83CF /* Connection.m in Sources */,
FBCC0E9D19F00659009729EB /* mkcert.c in Sources */,
FB290D3819B2C6E3004C83CF /* ConnectionHandler.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -825,6 +834,8 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "Limelight/Limelight-Prefix.pch";
HEADER_SEARCH_PATHS = (
@@ -841,6 +852,7 @@
"$(PROJECT_DIR)/libs/openssl/lib",
);
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
WRAPPER_EXTENSION = app;
};
name = Debug;
@@ -850,6 +862,8 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "Limelight/Limelight-Prefix.pch";
HEADER_SEARCH_PATHS = (
@@ -866,6 +880,7 @@
"$(PROJECT_DIR)/libs/openssl/lib",
);
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
WRAPPER_EXTENSION = app;
};
name = Release;

View File

@@ -18,6 +18,5 @@
- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;
+ (NSOperationQueue*) getMainOpQueue;
@end

View File

@@ -18,15 +18,9 @@ static NSOperationQueue* mainQueue;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
mainQueue = [[NSOperationQueue alloc]init];
return YES;
}
+ (NSOperationQueue*) getMainOpQueue
{
return mainQueue;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.

View File

@@ -14,6 +14,5 @@
@property BOOL paired;
- (id) initWithHost:(NSNetService*)host;
- (int) resolveHost;
@end

View File

@@ -8,10 +8,6 @@
#import "Computer.h"
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
@implementation Computer
- (id) initWithHost:(NSNetService *)host {
@@ -23,33 +19,4 @@
return self;
}
- (int) resolveHost
{
struct hostent *hostent;
if (inet_addr([self.hostName UTF8String]) != INADDR_NONE)
{
// Already an IP address
int addr = inet_addr([self.hostName UTF8String]);
NSLog(@"host address: %d", addr);
return addr;
}
else
{
hostent = gethostbyname([self.hostName UTF8String]);
if (hostent != NULL)
{
char* ipstr = inet_ntoa(*(struct in_addr*)hostent->h_addr_list[0]);
NSLog(@"Resolved %@ -> %s", self.hostName, ipstr);
int addr = inet_addr(ipstr);
NSLog(@"host address: %d", addr);
return addr;
}
else
{
NSLog(@"Failed to resolve host: %d", h_errno);
return -1;
}
}
}
@end

View File

@@ -8,10 +8,11 @@
#import <Foundation/Foundation.h>
#import "VideoDecoderRenderer.h"
#import "StreamConfiguration.h"
@interface Connection : NSOperation <NSStreamDelegate>
-(id) initWithHost:(int)ipaddr key:(NSData*)rikey keyId:(int)rikeyid width:(int)width height:(int)height refreshRate:(int)refreshRate renderer:(VideoDecoderRenderer*)myRenderer;
-(id) initWithConfig:(StreamConfiguration*)config renderer:(VideoDecoderRenderer*)myRenderer;
-(void) main;
@end

View File

@@ -193,22 +193,22 @@ void ClDisplayTransientMessage(char* message)
NSLog(@"DisplayTransientMessage: %s", message);
}
-(id) initWithHost:(int)ipaddr key:(NSData*)rikey keyId:(int)rikeyid width:(int)width height:(int)height refreshRate:(int)refreshRate renderer:(VideoDecoderRenderer*)myRenderer
-(id) initWithConfig:(StreamConfiguration*)config renderer:(VideoDecoderRenderer*)myRenderer
{
self = [super init];
host = ipaddr;
host = config.host;
renderer = myRenderer;
streamConfig.width = width;
streamConfig.height = height;
streamConfig.fps = 60;
streamConfig.bitrate = 5000;
streamConfig.width = config.width;
streamConfig.height = config.height;
streamConfig.fps = config.frameRate;
streamConfig.bitrate = config.bitRate;
streamConfig.packetSize = 1024;
memcpy(streamConfig.remoteInputAesKey, [rikey bytes], [rikey length]);
memcpy(streamConfig.remoteInputAesKey, [config.riKey bytes], [config.riKey length]);
memset(streamConfig.remoteInputAesIv, 0, 16);
rikeyid = htonl(rikeyid);
memcpy(streamConfig.remoteInputAesIv, &rikeyid, sizeof(rikeyid));
int riKeyId = htonl(config.riKeyId);
memcpy(streamConfig.remoteInputAesIv, &riKeyId, sizeof(riKeyId));
drCallbacks.setup = DrSetup;
drCallbacks.start = DrStart;

View File

@@ -1,19 +0,0 @@
//
// ConnectionHandler.h
// Limelight-iOS
//
// Created by Diego Waxemberg on 1/27/14.
// Copyright (c) 2014 Diego Waxemberg. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface ConnectionHandler : NSOperation
@property NSString* hostName;
@property int mode;
+ (void) pairWithHost:(NSString*)host;
+ (void) streamWithHost:(NSString*)host viewController:(UIViewController*)viewCont;
+ (NSString*) resolveHost:(NSString*)host;
@end

View File

@@ -1,336 +0,0 @@
//
// ConnectionHandler.m
// Limelight-iOS
//
// Created by Diego Waxemberg on 1/27/14.
// Copyright (c) 2014 Diego Waxemberg. All rights reserved.
//
#import "ConnectionHandler.h"
#import "AppDelegate.h"
#import <AdSupport/ASIdentifierManager.h>
#import "MainFrameViewController.h"
#include <libxml2/libxml/xmlreader.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@implementation ConnectionHandler
static const int PAIR_MODE = 0x1;
static const int STREAM_MODE = 0x2;
static MainFrameViewController* viewCont;
+ (void)streamWithHost:(NSString *)host viewController:(MainFrameViewController *)viewController
{
viewCont = viewController;
ConnectionHandler* streamHandler = [[ConnectionHandler alloc] initForStream:host];
[[AppDelegate getMainOpQueue] addOperation:streamHandler];
}
+ (void)pairWithHost:(NSString *)host
{
ConnectionHandler* pairHandler = [[ConnectionHandler alloc] initForPair:host];
[[AppDelegate getMainOpQueue]addOperation:pairHandler];
}
+ (NSString*) resolveHost:(NSString*)host
{
struct hostent *hostent;
if (inet_addr([host UTF8String]) != INADDR_NONE)
{
// Already an IP address
return host;
}
else
{
hostent = gethostbyname([host UTF8String]);
if (hostent != NULL)
{
char* ipstr = inet_ntoa(*(struct in_addr*)hostent->h_addr_list[0]);
NSLog(@"Resolved %@ -> %s", host, ipstr);
return [NSString stringWithUTF8String:ipstr];
}
else
{
NSLog(@"Failed to resolve host: %d", h_errno);
return nil;
}
}
}
+ (NSString*) getId
{
// we need to generate some unique id
NSUUID* uniqueId = [ASIdentifierManager sharedManager].advertisingIdentifier;
NSString* idString = [NSString stringWithString:[uniqueId UUIDString]];
//use just the last 12 digits because GameStream truncates id's
return [idString substringFromIndex:24];
}
+ (NSString*) getName
{
NSString* name = [UIDevice currentDevice].name;
NSLog(@"Device Name: %@", name);
//sanitize name
name = [name stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
return name;
}
- (id) initForStream:(NSString*)host
{
self = [super init];
self.hostName = host;
self.mode = STREAM_MODE;
return self;
}
- (id) initForPair:(NSString*)host
{
self = [super init];
self.hostName = host;
self.mode = PAIR_MODE;
return self;
}
- (void) main
{
switch (self.mode)
{
case STREAM_MODE:
{
bool pairState;
int err = [self pairState:&pairState];
if (err) {
NSLog(@"ERROR: Pair state error: %d", err);
break;
}
if (!pairState)
{
NSLog(@"WARN: Not paired with host!");
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Not Paired"
message:@"This device is not paired with the host."
delegate:nil
cancelButtonTitle:@"Okay"
otherButtonTitles:nil, nil];
[self showAlert:alert];
return;
}
//TODO: parse this from http request
unsigned int appId = 67339056;
NSData* applist = [self httpRequest:[NSString stringWithFormat:@"applist?uniqueid=%@", [ConnectionHandler getId]]];
NSString* streamString = [NSString stringWithFormat:@"http://%@:47989/launch?uniqueid=%@&appid=%u", [ConnectionHandler resolveHost:self.hostName], [ConnectionHandler getId], appId];
NSLog(@"host: %@", self.hostName);
NSURL* url = [[NSURL alloc] initWithString:streamString];
NSMutableURLRequest* request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setHTTPMethod:@"GET"];
NSURLResponse* response = nil;
NSData *response1 = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:NULL];
[viewCont performSelector:@selector(segueIntoStream) onThread:[NSThread mainThread] withObject:nil waitUntilDone:NO];
break;
}
case PAIR_MODE:
{
NSLog(@"Trying to pair to %@...", self.hostName);
bool pairState;
int err = [self pairState:&pairState];
if (err) {
NSLog(@"ERROR: Pair state error: %d", err);
break;
}
NSLog(@"Pair state: %i", pairState);
if(pairState)
{
UIAlertView* alert = [[UIAlertView alloc]initWithTitle:@"Pairing"
message:[NSString stringWithFormat:@"Already paired to:\n %@", self.hostName]
delegate:nil
cancelButtonTitle:@"Okay"
otherButtonTitles:nil, nil];
[self showAlert:alert];
NSLog(@"Showing alertview");
break;
}
// this will hang until it pairs successfully or unsuccessfully
NSData* pairResponse = [self httpRequest:[NSString stringWithFormat:@"pair?uniqueid=%@&devicename=%@", [ConnectionHandler getId], [ConnectionHandler getName]]];
void* buffer = [self getXMLBufferFromData:pairResponse];
if (buffer == NULL) {
NSLog(@"ERROR: Unable to allocate pair buffer.");
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Pairing"
message:[NSString stringWithFormat:@"Failed to pair with host:\n %@", self.hostName]
delegate:nil
cancelButtonTitle:@"Okay"
otherButtonTitles:nil, nil];
[self showAlert:alert];
break;
}
xmlDocPtr doc = xmlParseMemory(buffer, [pairResponse length]-1);
if (doc == NULL) {
NSLog(@"ERROR: An error occured trying to parse pair response.");
break;
}
xmlNodePtr node = xmlDocGetRootElement(doc);
node = node->xmlChildrenNode;
while (node != NULL) {
NSLog(@"Node: %s", node->name);
if (!xmlStrcmp(node->name, (const xmlChar*)"sessionid"))
{
xmlChar* sessionid = xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
if (xmlStrcmp(sessionid, (xmlChar*)"0")) {
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Pairing"
message:[NSString stringWithFormat:@"Successfully paired to host:\n %@", self.hostName]
delegate:nil
cancelButtonTitle:@"Okay"
otherButtonTitles:nil, nil];
[self showAlert:alert];
} else {
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Pairing"
message:[NSString stringWithFormat:@"Pairing was declined by host:\n %@", self.hostName]
delegate:nil
cancelButtonTitle:@"Okay"
otherButtonTitles:nil, nil];
[self showAlert:alert];
}
xmlFree(sessionid);
goto cleanup;
}
node = node->next;
}
NSLog(@"ERROR: Could not find \"sessionid\" element in XML");
cleanup:
xmlFreeNode(node);
break;
}
default:
{
NSLog(@"Invalid connection mode specified!!!");
}
}
}
- (int) pairState: (bool*)paired
{
int err;
NSData* pairData = [self httpRequest:[NSString stringWithFormat:@"pairstate?uniqueid=%@", [ConnectionHandler getId]]];
void* buffer = [self getXMLBufferFromData:pairData];
if (buffer == NULL) {
NSLog(@"ERROR: Unable to allocate pair state buffer.");
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Pairing"
message:[NSString stringWithFormat:@"Failed to get pair state with host:\n %@", self.hostName]
delegate:nil
cancelButtonTitle:@"Okay"
otherButtonTitles:nil, nil];
[self showAlert:alert];
return -1;
}
xmlDocPtr doc = xmlParseMemory(buffer, [pairData length]-1);
if (doc == NULL) {
NSLog(@"ERROR: An error occured trying to parse pair state.");
return -1;
}
xmlNodePtr node = xmlDocGetRootElement(doc);
while (node != NULL) {
NSLog(@"Node: %s", node->name);
if (!xmlStrcmp(node->name, (const xmlChar*)"paired"))
{
xmlChar* pairState = xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
*paired = !xmlStrcmp(pairState, (const xmlChar*)"1");
err = 0;
xmlFree(pairState);
goto cleanup;
}
node = node->xmlChildrenNode;
}
NSLog(@"ERROR: Could not find \"paired\" element in XML");
err = -2;
cleanup:
xmlFreeNode(node);
return err;
}
- (NSData*) httpRequest:(NSString*)args
{
NSString* requestString = [NSString stringWithFormat:@"http://%@:47989/%@", [ConnectionHandler resolveHost:self.hostName], args];
NSLog(@"Making HTTP request: %@", requestString);
NSURL* url = [[NSURL alloc] initWithString:requestString];
NSMutableURLRequest* request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setHTTPMethod:@"GET"];
[request setTimeoutInterval:7];
NSURLResponse* response = nil;
NSError* error = nil;
NSData* responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if (error != nil) {
NSLog(@"An error occured making HTTP request: %@\n Caused by: %@", [error localizedDescription], [error localizedFailureReason]);
}
return responseData;
}
- (void*) getXMLBufferFromData:(NSData*)data
{
if (data == nil) {
NSLog(@"ERROR: No data to get XML from!");
return NULL;
}
char* buffer = malloc([data length] + 1);
if (buffer == NULL) {
NSLog(@"ERROR: Unable to allocate XML buffer.");
return NULL;
}
[data getBytes:buffer length:[data length]];
buffer[[data length]] = 0;
NSLog(@"Buffer: %s", buffer);
//#AllTheJank
void* newBuffer = (void*)[[[NSString stringWithUTF8String:buffer]stringByReplacingOccurrencesOfString:@"UTF-16" withString:@"UTF-8" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [data length])] UTF8String];
NSLog(@"New Buffer: %s", newBuffer);
free(buffer);
return newBuffer;
}
- (void) showAlert:(UIAlertView*) alert
{
[alert performSelector:@selector(show) onThread:[NSThread mainThread] withObject:nil waitUntilDone:NO];
}
@end

View File

@@ -15,6 +15,11 @@
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "29x29",

View File

@@ -19,10 +19,8 @@
@property (strong, nonatomic) NSArray* streamConfigVals;
@property (strong, nonatomic) NSArray* hostPickerVals;
+ (int) getResolvedHost;
+ (NSData*) getRiKey;
+ (int) getRiKeyId;
- (void) segueIntoStream;
+ (NSString*) getHost;
@end

View File

@@ -7,7 +7,6 @@
//
#import "MainFrameViewController.h"
#import "ConnectionHandler.h"
#import "Computer.h"
#import "CryptoManager.h"
#import "HttpManager.h"
@@ -20,22 +19,11 @@
MDNSManager* _mDNSManager;
Computer* _selectedHost;
UIAlertView* _pairAlert;
StreamManager* _streamMan;
}
static int resolvedHost;
static NSData* riKey;
static int riKeyId;
static NSString* host;
+ (int) getResolvedHost {
return resolvedHost;
}
+ (NSData*) getRiKey {
return riKey;
}
+ (int) getRiKeyId {
return riKeyId;
+ (NSString*) getHost {
return host;
}
- (void)PairButton:(UIButton *)sender
@@ -77,14 +65,7 @@ static int riKeyId;
- (void)StreamButton:(UIButton *)sender
{
NSLog(@"Stream Button Pressed!");
_streamMan = [[StreamManager alloc] initWithHost:_selectedHost.hostName andViewController:self];
[_opQueue addOperation:_streamMan];
}
- (void) segueIntoStream {
resolvedHost = [_selectedHost resolveHost];
riKey = [_streamMan getRiKey];
riKeyId = [_streamMan getRiKeyId];
host = _selectedHost.hostName;
[self performSegueWithIdentifier:@"createStreamFrame" sender:self];
}

View File

@@ -23,7 +23,4 @@
- (NSData*) saltPIN:(NSString*)PIN;
- (void) initiatePair;
+ (NSData*) randomBytes:(NSInteger)length;
+ (NSString*) bytesToHex:(NSData*)data;
@end

View File

@@ -8,6 +8,7 @@
#import "PairManager.h"
#import "CryptoManager.h"
#import "Utils.h"
#include <dispatch/dispatch.h>
@@ -54,7 +55,7 @@
CryptoManager* cryptoMan = [[CryptoManager alloc] init];
NSData* aesKey = [cryptoMan createAESKeyFromSalt:salt];
NSData* randomChallenge = [PairManager randomBytes:16];
NSData* randomChallenge = [Utils randomBytes:16];
NSData* encryptedChallenge = [cryptoMan aesEncrypt:randomChallenge withKey:aesKey];
NSData* challengeResp = [_httpManager executeRequestSynchronously:[_httpManager newChallengeRequest:encryptedChallenge]];
@@ -65,13 +66,13 @@
return;
}
NSData* encServerChallengeResp = [self hexToBytes:[HttpManager getStringFromXML:challengeResp tag:@"challengeresponse"]];
NSData* encServerChallengeResp = [Utils hexToBytes:[HttpManager getStringFromXML:challengeResp tag:@"challengeresponse"]];
NSData* decServerChallengeResp = [cryptoMan aesDecrypt:encServerChallengeResp withKey:aesKey];
NSData* serverResponse = [decServerChallengeResp subdataWithRange:NSMakeRange(0, 20)];
NSData* serverChallenge = [decServerChallengeResp subdataWithRange:NSMakeRange(20, 16)];
NSData* clientSecret = [PairManager randomBytes:16];
NSData* clientSecret = [Utils randomBytes:16];
NSData* challengeRespHash = [cryptoMan SHA1HashData:[self concatData:[self concatData:serverChallenge with:[CryptoManager getSignatureFromCert:_cert]] with:clientSecret]];
NSData* challengeRespEncrypted = [cryptoMan aesEncrypt:challengeRespHash withKey:aesKey];
@@ -83,18 +84,18 @@
return;
}
NSData* serverSecretResp = [self hexToBytes:[HttpManager getStringFromXML:secretResp tag:@"pairingsecret"]];
NSData* serverSecretResp = [Utils hexToBytes:[HttpManager getStringFromXML:secretResp tag:@"pairingsecret"]];
NSData* serverSecret = [serverSecretResp subdataWithRange:NSMakeRange(0, 16)];
NSData* serverSignature = [serverSecretResp subdataWithRange:NSMakeRange(16, 256)];
if (![cryptoMan verifySignature:serverSecret withSignature:serverSignature andCert:[self hexToBytes:plainCert]]) {
if (![cryptoMan verifySignature:serverSecret withSignature:serverSignature andCert:[Utils hexToBytes:plainCert]]) {
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
//TODO: better message
[_callback pairFailed:@"verifySignature failed"];
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:[Utils hexToBytes:plainCert]]] with:serverSecret]];
if (![serverChallengeRespHash isEqual:serverResponse]) {
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
//TODO: better message
@@ -103,7 +104,7 @@
}
NSData* clientPairingSecret = [self concatData:clientSecret with:[cryptoMan signData:clientSecret withKey:[CryptoManager readKeyFromFile]]];
NSData* clientSecretResp = [_httpManager executeRequestSynchronously:[_httpManager newClientSecretRespRequest:[PairManager bytesToHex:clientPairingSecret]]];
NSData* clientSecretResp = [_httpManager executeRequestSynchronously:[_httpManager newClientSecretRespRequest:[Utils bytesToHex:clientPairingSecret]]];
if (![[HttpManager getStringFromXML:clientSecretResp tag:@"paired"] isEqual:@"1"]) {
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
//TODO: better message
@@ -131,52 +132,14 @@
NSString* PIN = [NSString stringWithFormat:@"%d%d%d%d",
arc4random() % 10, arc4random() % 10,
arc4random() % 10, arc4random() % 10];
NSLog(@"PIN: %@", PIN);
return PIN;
}
- (NSData*) saltPIN:(NSString*)PIN {
NSMutableData* saltedPIN = [[NSMutableData alloc] initWithCapacity:20];
[saltedPIN appendData:[PairManager randomBytes:16]];
[saltedPIN appendData:[Utils randomBytes:16]];
[saltedPIN appendBytes:[PIN UTF8String] length:4];
//NSLog(@"Salted PIN: %@", [saltedPIN description]);
return saltedPIN;
}
+ (NSData*) randomBytes:(NSInteger)length {
char* bytes = malloc(length);
arc4random_buf(bytes, length);
NSData* randomData = [NSData dataWithBytes:bytes length:length];
free(bytes);
return randomData;
}
- (NSData*) hexToBytes:(NSString*) hex {
int len = [hex length];
NSMutableData* data = [NSMutableData dataWithCapacity:len / 2];
char byteChars[3] = {'\0','\0','\0'};
unsigned long wholeByte;
const char *chars = [hex UTF8String];
int i = 0;
while (i < len) {
byteChars[0] = chars[i++];
byteChars[1] = chars[i++];
wholeByte = strtoul(byteChars, NULL, 16);
[data appendBytes:&wholeByte length:1];
}
return data;
}
+ (NSString*) bytesToHex:(NSData*)data {
const unsigned char* bytes = [data bytes];
NSMutableString *hex = [[NSMutableString alloc] init];
for (int i = 0; i < [data length]; i++) {
[hex appendFormat:@"%02X" , bytes[i]];
}
return hex;
}
@end

View File

@@ -0,0 +1,21 @@
//
// StreamConfiguration.h
// Limelight
//
// Created by Diego Waxemberg on 10/20/14.
// Copyright (c) 2014 Limelight Stream. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface StreamConfiguration : NSObject
@property int host;
@property int width;
@property int height;
@property int frameRate;
@property int bitRate;
@property int riKeyId;
@property NSData* riKey;
@end

View File

@@ -0,0 +1,13 @@
//
// StreamConfiguration.m
// Limelight
//
// Created by Diego Waxemberg on 10/20/14.
// Copyright (c) 2014 Limelight Stream. All rights reserved.
//
#import "StreamConfiguration.h"
@implementation StreamConfiguration
@synthesize host, width, height, frameRate, bitRate, riKeyId, riKey;
@end

View File

@@ -10,7 +10,7 @@
#import "MainFrameViewController.h"
#import "Connection.h"
#import "VideoDecoderRenderer.h"
#import "ConnectionHandler.h"
#import "StreamManager.h"
#include <sys/socket.h>
#include <netinet/in.h>
@@ -24,12 +24,9 @@
[UIApplication sharedApplication].idleTimerDisabled = YES;
VideoDecoderRenderer* renderer = [[VideoDecoderRenderer alloc]initWithView:self.view];
Connection* conn = [[Connection alloc] initWithHost:[MainFrameViewController getResolvedHost] key:[MainFrameViewController getRiKey] keyId:[MainFrameViewController getRiKeyId] width:1280 height:720 refreshRate:60 renderer:renderer];
StreamManager* streamMan = [[StreamManager alloc] initWithHost:[MainFrameViewController getHost] renderView:self.view];
NSOperationQueue* opQueue = [[NSOperationQueue alloc] init];
[opQueue addOperation:conn];
[opQueue addOperation:streamMan];
}
- (void)didReceiveMemoryWarning

View File

@@ -7,12 +7,9 @@
//
#import <Foundation/Foundation.h>
#import "MainFrameViewController.h"
@interface StreamManager : NSOperation
- (id) initWithHost:(NSString*)host andViewController:(MainFrameViewController*)viewCont;
- (NSData*) getRiKey;
- (int) getRiKeyId;
- (id) initWithHost:(NSString*)host renderView:(UIView*)view;
@end

View File

@@ -9,42 +9,49 @@
#import "StreamManager.h"
#import "CryptoManager.h"
#import "HttpManager.h"
#import "PairManager.h"
#import "Utils.h"
#import "Connection.h"
#import "StreamConfiguration.h"
@implementation StreamManager {
MainFrameViewController* _viewCont;
NSString* _host;
NSData* _riKey;
int _riKeyId;
UIView* _renderView;
}
- (id) initWithHost:(NSString*)host andViewController:(MainFrameViewController *)viewCont {
- (id) initWithHost:(NSString*)host renderView:(UIView*)view {
self = [super init];
_host = host;
_viewCont = viewCont;
_renderView = view;
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* riKey = [Utils randomBytes:16];
int riKeyId = arc4random();
NSData* launchResp = [hMan executeRequestSynchronously:[hMan newLaunchRequest:@"67339056" width:1280 height:720 refreshRate:60 rikey:[PairManager bytesToHex:_riKey] rikeyid:_riKeyId]];
NSData* launchResp = [hMan executeRequestSynchronously:[hMan newLaunchRequest:@"67339056" width:1920 height:1080 refreshRate:30 rikey:[Utils bytesToHex:riKey] rikeyid:riKeyId]];
[HttpManager getStringFromXML:launchResp tag:@"gamesession"];
[_viewCont segueIntoStream];
VideoDecoderRenderer* renderer = [[VideoDecoderRenderer alloc]initWithView:_renderView];
StreamConfiguration* config = [[StreamConfiguration alloc] init];
config.host = [Utils resolveHost:_host];
config.width = 1920;
config.height = 1080;
config.frameRate = 30;
config.bitRate = 10000;
config.riKey = riKey;
config.riKeyId = riKeyId;
Connection* conn = [[Connection alloc] initWithConfig:config renderer:renderer];
NSOperationQueue* opQueue = [[NSOperationQueue alloc] init];
[opQueue addOperation:conn];
}
@end

18
Limelight/Utils.h Normal file
View File

@@ -0,0 +1,18 @@
//
// Utils.h
// Limelight
//
// Created by Diego Waxemberg on 10/20/14.
// Copyright (c) 2014 Limelight Stream. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Utils : NSObject
+ (NSData*) randomBytes:(NSInteger)length;
+ (NSString*) bytesToHex:(NSData*)data;
+ (NSData*) hexToBytes:(NSString*) hex;
+ (int) resolveHost:(NSString*)host;
@end

76
Limelight/Utils.m Normal file
View File

@@ -0,0 +1,76 @@
//
// Utils.m
// Limelight
//
// Created by Diego Waxemberg on 10/20/14.
// Copyright (c) 2014 Limelight Stream. All rights reserved.
//
#import "Utils.h"
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
@implementation Utils
+ (NSData*) randomBytes:(NSInteger)length {
char* bytes = malloc(length);
arc4random_buf(bytes, length);
NSData* randomData = [NSData dataWithBytes:bytes length:length];
free(bytes);
return randomData;
}
+ (NSData*) hexToBytes:(NSString*) hex {
unsigned long len = [hex length];
NSMutableData* data = [NSMutableData dataWithCapacity:len / 2];
char byteChars[3] = {'\0','\0','\0'};
unsigned long wholeByte;
const char *chars = [hex UTF8String];
int i = 0;
while (i < len) {
byteChars[0] = chars[i++];
byteChars[1] = chars[i++];
wholeByte = strtoul(byteChars, NULL, 16);
[data appendBytes:&wholeByte length:1];
}
return data;
}
+ (NSString*) bytesToHex:(NSData*)data {
const unsigned char* bytes = [data bytes];
NSMutableString *hex = [[NSMutableString alloc] init];
for (int i = 0; i < [data length]; i++) {
[hex appendFormat:@"%02X" , bytes[i]];
}
return hex;
}
+ (int) resolveHost:(NSString*)host {
struct hostent *hostent;
if (inet_addr([host UTF8String]) != INADDR_NONE) {
// Already an IP address
int addr = inet_addr([host UTF8String]);
NSLog(@"host address: %d", addr);
return addr;
} else {
hostent = gethostbyname([host UTF8String]);
if (hostent != NULL) {
char* ipstr = inet_ntoa(*(struct in_addr*)hostent->h_addr_list[0]);
NSLog(@"Resolved %@ -> %s", host, ipstr);
int addr = inet_addr(ipstr);
NSLog(@"host address: %d", addr);
return addr;
} else {
NSLog(@"Failed to resolve host: %d", h_errno);
return -1;
}
}
}
@end