mirror of
https://github.com/moonlight-stream/moonlight-ios.git
synced 2026-04-03 06:26:09 +00:00
Created http response class and added error checking
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
#import "AppManager.h"
|
||||
#import "CryptoManager.h"
|
||||
#import "Utils.h"
|
||||
#import "HttpResponse.h"
|
||||
|
||||
@implementation AppManager {
|
||||
NSOperationQueue* _opQueue;
|
||||
@@ -60,8 +61,9 @@
|
||||
}
|
||||
if (appImage == nil) {
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:_host.address uniqueId:_uniqueId deviceName:deviceName cert:_cert];
|
||||
NSData* appAsset = [hMan executeRequestSynchronously:[hMan newAppAssetRequestWithAppId:app.appId]];
|
||||
appImage = [UIImage imageWithData:appAsset];
|
||||
HttpResponse* appAssetResp = [hMan executeRequestSynchronously:[hMan newAppAssetRequestWithAppId:app.appId]];
|
||||
|
||||
appImage = [UIImage imageWithData:appAssetResp.responseData];
|
||||
app.appImage = appImage;
|
||||
if (appImage != nil) {
|
||||
@synchronized(_imageCache) {
|
||||
|
||||
@@ -39,14 +39,14 @@
|
||||
|
||||
- (void) discoverHost:(NSString *)hostAddress withCallback:(void (^)(Host *))callback {
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:hostAddress uniqueId:_uniqueId deviceName:deviceName cert:_cert];
|
||||
NSData* serverInfoData = [hMan executeRequestSynchronously:[hMan newServerInfoRequest]];
|
||||
HttpResponse* serverInfoResponse = [hMan executeRequestSynchronously:[hMan newServerInfoRequest]];
|
||||
|
||||
Host* host = nil;
|
||||
if ([[HttpManager getStatusStringFromXML:serverInfoData] isEqualToString:@"OK"]) {
|
||||
if ([serverInfoResponse isStatusOk]) {
|
||||
DataManager* dataMan = [[DataManager alloc] init];
|
||||
host = [dataMan createHost];
|
||||
host.address = hostAddress;
|
||||
[HttpManager populateHostFromXML:serverInfoData host:host];
|
||||
[serverInfoResponse populateHost:host];
|
||||
if (![self addHostToDiscovery:host]) {
|
||||
[dataMan removeHost:host];
|
||||
}
|
||||
|
||||
@@ -43,18 +43,18 @@ static const float POLL_RATE = 2.0f; // Poll every 2 seconds
|
||||
BOOL receivedResponse = NO;
|
||||
if (!self.cancelled && _host.localAddress != nil) {
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:_host.localAddress uniqueId:_uniqueId deviceName:deviceName cert:_cert];
|
||||
NSData* serverInfoData = [hMan executeRequestSynchronously:[hMan newServerInfoRequest]];
|
||||
if ([[HttpManager getStatusStringFromXML:serverInfoData] isEqualToString:@"OK"]) {
|
||||
[HttpManager populateHostFromXML:serverInfoData host:_host];
|
||||
HttpResponse* serverInfoResp = [hMan executeRequestSynchronously:[hMan newServerInfoRequest]];
|
||||
if ([serverInfoResp isStatusOk]) {
|
||||
[serverInfoResp populateHost:_host];
|
||||
_host.address = _host.localAddress;
|
||||
receivedResponse = YES;
|
||||
}
|
||||
}
|
||||
if (!self.cancelled && !receivedResponse && _host.externalAddress != nil) {
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:_host.externalAddress uniqueId:_uniqueId deviceName:deviceName cert:_cert];
|
||||
NSData* serverInfoData = [hMan executeRequestSynchronously:[hMan newServerInfoRequest]];
|
||||
if ([[HttpManager getStatusStringFromXML:serverInfoData] isEqualToString:@"OK"]) {
|
||||
[HttpManager populateHostFromXML:serverInfoData host:_host];
|
||||
HttpResponse* serverInfoResp = [hMan executeRequestSynchronously:[hMan newServerInfoRequest]];
|
||||
if ([serverInfoResp isStatusOk]) {
|
||||
[serverInfoResp populateHost:_host];
|
||||
_host.address = _host.externalAddress;
|
||||
receivedResponse = YES;
|
||||
}
|
||||
@@ -62,9 +62,9 @@ static const float POLL_RATE = 2.0f; // Poll every 2 seconds
|
||||
|
||||
if (!self.cancelled && !receivedResponse && _host.address != nil) {
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:_host.address uniqueId:_uniqueId deviceName:deviceName cert:_cert];
|
||||
NSData* serverInfoData = [hMan executeRequestSynchronously:[hMan newServerInfoRequest]];
|
||||
if ([[HttpManager getStatusStringFromXML:serverInfoData] isEqualToString:@"OK"]) {
|
||||
[HttpManager populateHostFromXML:serverInfoData host:_host];
|
||||
HttpResponse* serverInfoResp = [hMan executeRequestSynchronously:[hMan newServerInfoRequest]];
|
||||
if ([serverInfoResp isStatusOk]) {
|
||||
[serverInfoResp populateHost:_host];
|
||||
receivedResponse = YES;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,14 +8,10 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "Host.h"
|
||||
#import "HttpResponse.h"
|
||||
|
||||
@interface HttpManager : NSObject <NSURLConnectionDelegate, NSURLConnectionDataDelegate>
|
||||
|
||||
+ (NSArray*) getAppListFromXML:(NSData*)xml;
|
||||
+ (void) populateHostFromXML:(NSData*)xml host:(Host*)host;
|
||||
+ (NSString*) getStringFromXML:(NSData*)xml tag:(NSString*)tag;
|
||||
+ (NSString*) getStatusStringFromXML:(NSData*)xml;
|
||||
|
||||
- (id) initWithHost:(NSString*) host uniqueId:(NSString*) uniqueId deviceName:(NSString*) deviceName cert:(NSData*) cert;
|
||||
- (NSURLRequest*) newPairRequest:(NSData*)salt;
|
||||
- (NSURLRequest*) newUnpairRequest;
|
||||
@@ -29,7 +25,9 @@
|
||||
- (NSURLRequest*) newResumeRequestWithRiKey:(NSString*)riKey riKeyId:(int)riKeyId;
|
||||
- (NSURLRequest*) newQuitAppRequest;
|
||||
- (NSURLRequest*) newAppAssetRequestWithAppId:(NSString*)appId;
|
||||
- (NSData*) executeRequestSynchronously:(NSURLRequest*)request;
|
||||
- (HttpResponse*) executeRequestSynchronously:(NSURLRequest*)request;
|
||||
- (void) executeRequest:(NSURLRequest*)request;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@@ -26,207 +26,6 @@
|
||||
|
||||
static const NSString* PORT = @"47984";
|
||||
|
||||
+ (NSArray*) getAppListFromXML:(NSData*)xml {
|
||||
xmlDocPtr docPtr = xmlParseMemory([xml bytes], (int)[xml length]);
|
||||
|
||||
if (docPtr == NULL) {
|
||||
NSLog(@"ERROR: An error occured trying to parse xml.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
xmlNodePtr node;
|
||||
xmlNodePtr rootNode = node = xmlDocGetRootElement(docPtr);
|
||||
|
||||
// Check root status_code
|
||||
if (![HttpManager verifyStatus: rootNode]) {
|
||||
NSLog(@"ERROR: Request returned with failure status");
|
||||
xmlFreeDoc(docPtr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Skip the root node
|
||||
node = node->children;
|
||||
|
||||
NSMutableArray* appList = [[NSMutableArray alloc] init];
|
||||
|
||||
while (node != NULL) {
|
||||
//NSLog(@"node: %s", node->name);
|
||||
if (!xmlStrcmp(node->name, (const xmlChar*)"App")) {
|
||||
xmlNodePtr appInfoNode = node->xmlChildrenNode;
|
||||
NSString* appName;
|
||||
NSString* appId;
|
||||
BOOL appIsRunning = NO;
|
||||
while (appInfoNode != NULL) {
|
||||
//NSLog(@"appInfoNode: %s", appInfoNode->name);
|
||||
if (!xmlStrcmp(appInfoNode->name, (const xmlChar*)"AppTitle")) {
|
||||
xmlChar* nodeVal = xmlNodeListGetString(docPtr, appInfoNode->xmlChildrenNode, 1);
|
||||
appName = [[NSString alloc] initWithCString:(const char*)nodeVal encoding:NSUTF8StringEncoding];
|
||||
xmlFree(nodeVal);
|
||||
} else if (!xmlStrcmp(appInfoNode->name, (const xmlChar*)"ID")) {
|
||||
xmlChar* nodeVal = xmlNodeListGetString(docPtr, appInfoNode->xmlChildrenNode, 1);
|
||||
appId = [[NSString alloc] initWithCString:(const char*)nodeVal encoding:NSUTF8StringEncoding];
|
||||
xmlFree(nodeVal);
|
||||
} else if (!xmlStrcmp(appInfoNode->name, (const xmlChar*)"IsRunning")) {
|
||||
xmlChar* nodeVal = xmlNodeListGetString(docPtr, appInfoNode->xmlChildrenNode, 1);
|
||||
appIsRunning = [[[NSString alloc] initWithCString:(const char*)nodeVal encoding:NSUTF8StringEncoding] isEqualToString:@"1"];
|
||||
xmlFree(nodeVal);
|
||||
}
|
||||
appInfoNode = appInfoNode->next;
|
||||
}
|
||||
App* app = [[App alloc] init];
|
||||
app.appName = appName;
|
||||
app.appId = appId;
|
||||
app.isRunning = appIsRunning;
|
||||
[appList addObject:app];
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
xmlFreeDoc(docPtr);
|
||||
|
||||
return appList;
|
||||
}
|
||||
|
||||
+ (void) populateHostFromXML:(NSData*)xml host:(Host*)host {
|
||||
xmlDocPtr docPtr = xmlParseMemory([xml bytes], (int)[xml length]);
|
||||
|
||||
if (docPtr == NULL) {
|
||||
NSLog(@"ERROR: An error occured trying to parse xml.");
|
||||
return;
|
||||
}
|
||||
|
||||
xmlNodePtr node;
|
||||
xmlNodePtr rootNode = node = xmlDocGetRootElement(docPtr);
|
||||
|
||||
// Check root status_code
|
||||
if (![HttpManager verifyStatus: rootNode]) {
|
||||
NSLog(@"ERROR: Request returned with failure status");
|
||||
xmlFreeDoc(docPtr);
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip the root node
|
||||
node = node->children;
|
||||
|
||||
while (node != NULL) {
|
||||
//NSLog(@"node: %s", node->name);
|
||||
if (!xmlStrcmp(node->name, (const xmlChar*)"hostname")) {
|
||||
xmlChar* nodeVal = xmlNodeListGetString(docPtr, node->xmlChildrenNode, 1);
|
||||
host.name = [[NSString alloc] initWithCString:(const char*)nodeVal encoding:NSUTF8StringEncoding];
|
||||
xmlFree(nodeVal);
|
||||
} else if (!xmlStrcmp(node->name, (const xmlChar*)"ExternalIP")) {
|
||||
xmlChar* nodeVal = xmlNodeListGetString(docPtr, node->xmlChildrenNode, 1);
|
||||
host.externalAddress = [[NSString alloc] initWithCString:(const char*)nodeVal encoding:NSUTF8StringEncoding];
|
||||
xmlFree(nodeVal);
|
||||
} else if (!xmlStrcmp(node->name, (const xmlChar*)"LocalIP")) {
|
||||
xmlChar* nodeVal = xmlNodeListGetString(docPtr, node->xmlChildrenNode, 1);
|
||||
host.localAddress = [[NSString alloc] initWithCString:(const char*)nodeVal encoding:NSUTF8StringEncoding];
|
||||
xmlFree(nodeVal);
|
||||
} else if (!xmlStrcmp(node->name, (const xmlChar*)"uniqueid")) {
|
||||
xmlChar* nodeVal = xmlNodeListGetString(docPtr, node->xmlChildrenNode, 1);
|
||||
host.uuid = [[NSString alloc] initWithCString:(const char*)nodeVal encoding:NSUTF8StringEncoding];
|
||||
xmlFree(nodeVal);
|
||||
} else if (!xmlStrcmp(node->name, (const xmlChar*)"mac")) {
|
||||
xmlChar* nodeVal = xmlNodeListGetString(docPtr, node->xmlChildrenNode, 1);
|
||||
host.mac = [[NSString alloc] initWithCString:(const char*)nodeVal encoding:NSUTF8StringEncoding];
|
||||
xmlFree(nodeVal);
|
||||
} else if (!xmlStrcmp(node->name, (const xmlChar*)"PairStatus")) {
|
||||
xmlChar* nodeVal = xmlNodeListGetString(docPtr, node->xmlChildrenNode, 1);
|
||||
host.pairState = [[[NSString alloc] initWithCString:(const char*)nodeVal encoding:NSUTF8StringEncoding] isEqualToString:@"1"] ? PairStatePaired : PairStateUnpaired;
|
||||
xmlFree(nodeVal);
|
||||
}
|
||||
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
xmlFreeDoc(docPtr);
|
||||
}
|
||||
|
||||
+ (NSString*) getStatusStringFromXML:(NSData*)xml {
|
||||
xmlDocPtr docPtr = xmlParseMemory([xml bytes], (int)[xml length]);
|
||||
|
||||
if (docPtr == NULL) {
|
||||
NSLog(@"ERROR: An error occured trying to parse xml.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NSString* string;
|
||||
xmlNodePtr rootNode = xmlDocGetRootElement(docPtr);
|
||||
if (rootNode == NULL) {
|
||||
NSLog(@"ERROR: No root XML element.");
|
||||
xmlFreeDoc(docPtr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
string = [HttpManager getStatusMessage: rootNode];
|
||||
|
||||
xmlFreeDoc(docPtr);
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
+ (NSString*) getStringFromXML:(NSData*)xml tag:(NSString*)tag {
|
||||
xmlDocPtr docPtr = xmlParseMemory([xml bytes], (int)[xml length]);
|
||||
|
||||
if (docPtr == NULL) {
|
||||
NSLog(@"ERROR: An error occured trying to parse xml.");
|
||||
return NULL;
|
||||
}
|
||||
NSString* value;
|
||||
xmlNodePtr node;
|
||||
xmlNodePtr rootNode = node = xmlDocGetRootElement(docPtr);
|
||||
|
||||
// Check root status_code
|
||||
if (![HttpManager verifyStatus: rootNode]) {
|
||||
NSLog(@"ERROR: Request returned with failure status");
|
||||
xmlFreeDoc(docPtr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Skip the root node
|
||||
node = node->children;
|
||||
|
||||
while (node != NULL) {
|
||||
//NSLog(@"node: %s", node->name);
|
||||
if (!xmlStrcmp(node->name, (const xmlChar*)[tag UTF8String])) {
|
||||
xmlChar* nodeVal = xmlNodeListGetString(docPtr, node->xmlChildrenNode, 1);
|
||||
value = [[NSString alloc] initWithCString:(const char*)nodeVal encoding:NSUTF8StringEncoding];
|
||||
xmlFree(nodeVal);
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
//NSLog(@"xmlValue: %@", value);
|
||||
|
||||
xmlFreeDoc(docPtr);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
+ (NSString*) getStatusMessage:(xmlNodePtr)docRoot {
|
||||
xmlChar* statusMsgXml = xmlGetProp(docRoot, (const xmlChar*)"status_message");
|
||||
NSString* statusMsg;
|
||||
if (statusMsgXml != NULL) {
|
||||
statusMsg = [NSString stringWithUTF8String:(const char*)statusMsgXml];
|
||||
xmlFree(statusMsgXml);
|
||||
}
|
||||
else {
|
||||
statusMsg = @"Server Error";
|
||||
}
|
||||
|
||||
return statusMsg;
|
||||
}
|
||||
|
||||
+ (bool) verifyStatus:(xmlNodePtr)docRoot {
|
||||
xmlChar* statusStr = xmlGetProp(docRoot, (const xmlChar*)"status_code");
|
||||
if (statusStr != NULL) {
|
||||
int status = [[NSString stringWithUTF8String:(const char*)statusStr] intValue];
|
||||
xmlFree(statusStr);
|
||||
return status == 200;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
+ (NSData*) fixXmlVersion:(NSData*) xmlData {
|
||||
NSString* dataString = [[NSString alloc] initWithData:xmlData encoding:NSUTF8StringEncoding];
|
||||
NSString* xmlString = [dataString stringByReplacingOccurrencesOfString:@"UTF-16" withString:@"UTF-8" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [dataString length])];
|
||||
@@ -247,14 +46,14 @@ static const NSString* PORT = @"47984";
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSData*) executeRequestSynchronously:(NSURLRequest*)request {
|
||||
- (HttpResponse*) executeRequestSynchronously:(NSURLRequest*)request {
|
||||
NSLog(@"Making Request: %@", request);
|
||||
[_respData setLength:0];
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
[NSURLConnection connectionWithRequest:request delegate:self];
|
||||
});
|
||||
dispatch_semaphore_wait(_requestLock, DISPATCH_TIME_FOREVER);
|
||||
return _requestResp;
|
||||
return [HttpResponse responseWithData:_requestResp];
|
||||
}
|
||||
|
||||
- (void) executeRequest:(NSURLRequest*)request {
|
||||
|
||||
26
Limelight/Network/HttpResponse.h
Normal file
26
Limelight/Network/HttpResponse.h
Normal file
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// HttpResponse.h
|
||||
// Limelight
|
||||
//
|
||||
// Created by Diego Waxemberg on 1/30/15.
|
||||
// Copyright (c) 2015 Limelight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "Host.h"
|
||||
|
||||
@interface HttpResponse : NSObject
|
||||
|
||||
@property (nonatomic) NSInteger statusCode;
|
||||
@property (nonatomic) NSString* statusMessage;
|
||||
@property (nonatomic) NSData* responseData;
|
||||
|
||||
+ (HttpResponse*) responseWithData:(NSData*)xml;
|
||||
|
||||
- (NSString*) parseStringTag:(NSString*)tag;
|
||||
- (BOOL)parseIntTag:(NSString *)tag value:(NSInteger*)value;
|
||||
- (BOOL) isStatusOk;
|
||||
- (BOOL) populateHost:(Host*)host;
|
||||
- (NSArray*) getAppList;
|
||||
|
||||
@end
|
||||
222
Limelight/Network/HttpResponse.m
Normal file
222
Limelight/Network/HttpResponse.m
Normal file
@@ -0,0 +1,222 @@
|
||||
//
|
||||
// HttpResponse.m
|
||||
// Limelight
|
||||
//
|
||||
// Created by Diego Waxemberg on 1/30/15.
|
||||
// Copyright (c) 2015 Limelight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "HttpResponse.h"
|
||||
#import "App.h"
|
||||
#import <libxml2/libxml/xmlreader.h>
|
||||
|
||||
@implementation HttpResponse
|
||||
|
||||
+ (HttpResponse*) responseWithData:(NSData*)xml {
|
||||
HttpResponse* response = [[HttpResponse alloc] init];
|
||||
response.responseData = xml;
|
||||
|
||||
xmlDocPtr docPtr = xmlParseMemory([xml bytes], (int)[xml length]);
|
||||
|
||||
if (docPtr == NULL) {
|
||||
NSLog(@"ERROR: An error occured trying to parse xml.");
|
||||
return response;
|
||||
}
|
||||
|
||||
xmlNodePtr rootNode = xmlDocGetRootElement(docPtr);
|
||||
if (rootNode == NULL) {
|
||||
NSLog(@"ERROR: No root XML element.");
|
||||
xmlFreeDoc(docPtr);
|
||||
return response;
|
||||
}
|
||||
|
||||
xmlChar* statusStr = xmlGetProp(rootNode, (const xmlChar*)"status_code");
|
||||
if (statusStr != NULL) {
|
||||
int status = [[NSString stringWithUTF8String:(const char*)statusStr] intValue];
|
||||
xmlFree(statusStr);
|
||||
response.statusCode = status;
|
||||
}
|
||||
|
||||
xmlChar* statusMsgXml = xmlGetProp(rootNode, (const xmlChar*)"status_message");
|
||||
NSString* statusMsg;
|
||||
if (statusMsgXml != NULL) {
|
||||
statusMsg = [NSString stringWithUTF8String:(const char*)statusMsgXml];
|
||||
xmlFree(statusMsgXml);
|
||||
}
|
||||
else {
|
||||
statusMsg = @"Server Error";
|
||||
}
|
||||
response.statusMessage = statusMsg;
|
||||
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
- (NSString*)parseStringTag:(NSString *)tag {
|
||||
xmlDocPtr docPtr = xmlParseMemory([self.responseData bytes], (int)[self.responseData length]);
|
||||
|
||||
if (docPtr == NULL) {
|
||||
NSLog(@"ERROR: An error occured trying to parse xml.");
|
||||
return nil;
|
||||
}
|
||||
|
||||
xmlNodePtr node = xmlDocGetRootElement(docPtr);
|
||||
|
||||
// Check root status_code
|
||||
if (![self isStatusOk]) {
|
||||
NSLog(@"ERROR: Request returned with failure status");
|
||||
xmlFreeDoc(docPtr);
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Skip the root node
|
||||
node = node->children;
|
||||
|
||||
NSString* value;
|
||||
while (node != NULL) {
|
||||
//NSLog(@"node: %s", node->name);
|
||||
if (!xmlStrcmp(node->name, (const xmlChar*)[tag UTF8String])) {
|
||||
xmlChar* nodeVal = xmlNodeListGetString(docPtr, node->xmlChildrenNode, 1);
|
||||
value = [[NSString alloc] initWithCString:(const char*)nodeVal encoding:NSUTF8StringEncoding];
|
||||
xmlFree(nodeVal);
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
//NSLog(@"xmlValue: %@", value);
|
||||
|
||||
xmlFreeDoc(docPtr);
|
||||
return value;
|
||||
}
|
||||
|
||||
- (BOOL)parseIntTag:(NSString *)tag value:(NSInteger*)value {
|
||||
NSString* stringVal = [self parseStringTag:tag];
|
||||
if (stringVal != nil) {
|
||||
*value = [stringVal integerValue];
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL) isStatusOk {
|
||||
return self.statusCode == 200;
|
||||
}
|
||||
|
||||
- (BOOL) populateHost:(Host*)host {
|
||||
xmlDocPtr docPtr = xmlParseMemory([self.responseData bytes], (int)[self.responseData length]);
|
||||
|
||||
if (docPtr == NULL) {
|
||||
NSLog(@"ERROR: An error occured trying to parse xml.");
|
||||
return false;
|
||||
}
|
||||
|
||||
xmlNodePtr node = xmlDocGetRootElement(docPtr);
|
||||
|
||||
// Check root status_code
|
||||
if (![self isStatusOk]) {
|
||||
NSLog(@"ERROR: Request returned with failure status");
|
||||
xmlFreeDoc(docPtr);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip the root node
|
||||
node = node->children;
|
||||
|
||||
while (node != NULL) {
|
||||
//NSLog(@"node: %s", node->name);
|
||||
if (!xmlStrcmp(node->name, (const xmlChar*)"hostname")) {
|
||||
xmlChar* nodeVal = xmlNodeListGetString(docPtr, node->xmlChildrenNode, 1);
|
||||
host.name = [[NSString alloc] initWithCString:(const char*)nodeVal encoding:NSUTF8StringEncoding];
|
||||
xmlFree(nodeVal);
|
||||
} else if (!xmlStrcmp(node->name, (const xmlChar*)"ExternalIP")) {
|
||||
xmlChar* nodeVal = xmlNodeListGetString(docPtr, node->xmlChildrenNode, 1);
|
||||
host.externalAddress = [[NSString alloc] initWithCString:(const char*)nodeVal encoding:NSUTF8StringEncoding];
|
||||
xmlFree(nodeVal);
|
||||
} else if (!xmlStrcmp(node->name, (const xmlChar*)"LocalIP")) {
|
||||
xmlChar* nodeVal = xmlNodeListGetString(docPtr, node->xmlChildrenNode, 1);
|
||||
host.localAddress = [[NSString alloc] initWithCString:(const char*)nodeVal encoding:NSUTF8StringEncoding];
|
||||
xmlFree(nodeVal);
|
||||
} else if (!xmlStrcmp(node->name, (const xmlChar*)"uniqueid")) {
|
||||
xmlChar* nodeVal = xmlNodeListGetString(docPtr, node->xmlChildrenNode, 1);
|
||||
host.uuid = [[NSString alloc] initWithCString:(const char*)nodeVal encoding:NSUTF8StringEncoding];
|
||||
xmlFree(nodeVal);
|
||||
} else if (!xmlStrcmp(node->name, (const xmlChar*)"mac")) {
|
||||
xmlChar* nodeVal = xmlNodeListGetString(docPtr, node->xmlChildrenNode, 1);
|
||||
host.mac = [[NSString alloc] initWithCString:(const char*)nodeVal encoding:NSUTF8StringEncoding];
|
||||
xmlFree(nodeVal);
|
||||
} else if (!xmlStrcmp(node->name, (const xmlChar*)"PairStatus")) {
|
||||
xmlChar* nodeVal = xmlNodeListGetString(docPtr, node->xmlChildrenNode, 1);
|
||||
host.pairState = [[[NSString alloc] initWithCString:(const char*)nodeVal encoding:NSUTF8StringEncoding] isEqualToString:@"1"] ? PairStatePaired : PairStateUnpaired;
|
||||
xmlFree(nodeVal);
|
||||
}
|
||||
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
xmlFreeDoc(docPtr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
- (NSArray*) getAppList {
|
||||
xmlDocPtr docPtr = xmlParseMemory([self.responseData bytes], (int)[self.responseData length]);
|
||||
|
||||
if (docPtr == NULL) {
|
||||
NSLog(@"ERROR: An error occured trying to parse xml.");
|
||||
return nil;
|
||||
}
|
||||
|
||||
xmlNodePtr node = xmlDocGetRootElement(docPtr);
|
||||
|
||||
// Check root status_code
|
||||
if (![self isStatusOk]) {
|
||||
NSLog(@"ERROR: Request returned with failure status");
|
||||
xmlFreeDoc(docPtr);
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Skip the root node
|
||||
node = node->children;
|
||||
|
||||
NSMutableArray* appList = [[NSMutableArray alloc] init];
|
||||
|
||||
while (node != NULL) {
|
||||
//NSLog(@"node: %s", node->name);
|
||||
if (!xmlStrcmp(node->name, (const xmlChar*)"App")) {
|
||||
xmlNodePtr appInfoNode = node->xmlChildrenNode;
|
||||
NSString* appName;
|
||||
NSString* appId;
|
||||
BOOL appIsRunning = NO;
|
||||
while (appInfoNode != NULL) {
|
||||
//NSLog(@"appInfoNode: %s", appInfoNode->name);
|
||||
if (!xmlStrcmp(appInfoNode->name, (const xmlChar*)"AppTitle")) {
|
||||
xmlChar* nodeVal = xmlNodeListGetString(docPtr, appInfoNode->xmlChildrenNode, 1);
|
||||
appName = [[NSString alloc] initWithCString:(const char*)nodeVal encoding:NSUTF8StringEncoding];
|
||||
xmlFree(nodeVal);
|
||||
} else if (!xmlStrcmp(appInfoNode->name, (const xmlChar*)"ID")) {
|
||||
xmlChar* nodeVal = xmlNodeListGetString(docPtr, appInfoNode->xmlChildrenNode, 1);
|
||||
appId = [[NSString alloc] initWithCString:(const char*)nodeVal encoding:NSUTF8StringEncoding];
|
||||
xmlFree(nodeVal);
|
||||
} else if (!xmlStrcmp(appInfoNode->name, (const xmlChar*)"IsRunning")) {
|
||||
xmlChar* nodeVal = xmlNodeListGetString(docPtr, appInfoNode->xmlChildrenNode, 1);
|
||||
appIsRunning = [[[NSString alloc] initWithCString:(const char*)nodeVal encoding:NSUTF8StringEncoding] isEqualToString:@"1"];
|
||||
xmlFree(nodeVal);
|
||||
}
|
||||
appInfoNode = appInfoNode->next;
|
||||
}
|
||||
App* app = [[App alloc] init];
|
||||
app.appName = appName;
|
||||
app.appId = appId;
|
||||
app.isRunning = appIsRunning;
|
||||
[appList addObject:app];
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
xmlFreeDoc(docPtr);
|
||||
|
||||
return appList;
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
@@ -9,6 +9,7 @@
|
||||
#import "PairManager.h"
|
||||
#import "CryptoManager.h"
|
||||
#import "Utils.h"
|
||||
#import "HttpResponse.h"
|
||||
|
||||
#include <dispatch/dispatch.h>
|
||||
|
||||
@@ -27,18 +28,19 @@
|
||||
}
|
||||
|
||||
- (void) main {
|
||||
NSData* serverInfo = [_httpManager executeRequestSynchronously:[_httpManager newServerInfoRequest]];
|
||||
if (serverInfo == NULL) {
|
||||
HttpResponse* serverInfo = [_httpManager executeRequestSynchronously:[_httpManager newServerInfoRequest]];
|
||||
if (serverInfo == nil) {
|
||||
[_callback pairFailed:@"Unable to connect to PC"];
|
||||
return;
|
||||
}
|
||||
if (![[HttpManager getStringFromXML:serverInfo tag:@"currentgame"] isEqual:@"0"]) {
|
||||
[_callback pairFailed:@"You must stop streaming before attempting to pair."];
|
||||
}
|
||||
else if (![[HttpManager getStringFromXML:serverInfo tag:@"PairStatus"] isEqual:@"1"]) {
|
||||
[self initiatePair];
|
||||
} else {
|
||||
[_callback alreadyPaired];
|
||||
if ([serverInfo isStatusOk]) {
|
||||
if (![[serverInfo parseStringTag:@"currentgame"] isEqual:@"0"]) {
|
||||
[_callback pairFailed:@"You must stop streaming before attempting to pair."];
|
||||
} else if (![[serverInfo parseStringTag:@"PairStatus"] isEqual:@"1"]) {
|
||||
[self initiatePair];
|
||||
} else {
|
||||
[_callback alreadyPaired];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,16 +50,18 @@
|
||||
NSLog(@"PIN: %@, saltedPIN: %@", PIN, salt);
|
||||
[_callback showPIN:PIN];
|
||||
|
||||
NSData* pairResp = [_httpManager executeRequestSynchronously:[_httpManager newPairRequest:salt]];
|
||||
NSString* pairedString;
|
||||
pairedString = [HttpManager getStringFromXML:pairResp tag:@"paired"];
|
||||
if (pairedString == NULL || ![pairedString isEqualToString:@"1"]) {
|
||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||
HttpResponse* pairResp = [_httpManager executeRequestSynchronously:[_httpManager newPairRequest:salt]];
|
||||
if (![self verifyResponseStatus:pairResp]) {
|
||||
return;
|
||||
}
|
||||
NSInteger* pairedStatus;
|
||||
if (![pairResp parseIntTag:@"paired" value:pairedStatus] || !pairedStatus) {
|
||||
[_httpManager executeRequest:[_httpManager newUnpairRequest]];
|
||||
[_callback pairFailed:@"Pairing was declined by the target."];
|
||||
return;
|
||||
}
|
||||
|
||||
NSString* plainCert = [HttpManager getStringFromXML:pairResp tag:@"plaincert"];
|
||||
NSString* plainCert = [pairResp parseStringTag:@"plaincert"];
|
||||
|
||||
CryptoManager* cryptoMan = [[CryptoManager alloc] init];
|
||||
NSData* aesKey = [cryptoMan createAESKeyFromSalt:salt];
|
||||
@@ -65,15 +69,17 @@
|
||||
NSData* randomChallenge = [Utils randomBytes:16];
|
||||
NSData* encryptedChallenge = [cryptoMan aesEncrypt:randomChallenge withKey:aesKey];
|
||||
|
||||
NSData* challengeResp = [_httpManager executeRequestSynchronously:[_httpManager newChallengeRequest:encryptedChallenge]];
|
||||
pairedString = [HttpManager getStringFromXML:challengeResp tag:@"paired"];
|
||||
if (pairedString == NULL || ![pairedString isEqualToString:@"1"]) {
|
||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||
HttpResponse* challengeResp = [_httpManager executeRequestSynchronously:[_httpManager newChallengeRequest:encryptedChallenge]];
|
||||
if (![self verifyResponseStatus:challengeResp]) {
|
||||
return;
|
||||
}
|
||||
if (![challengeResp parseIntTag:@"paired" value:pairedStatus] || !pairedStatus) {
|
||||
[_httpManager executeRequest:[_httpManager newUnpairRequest]];
|
||||
[_callback pairFailed:@"Pairing stage #2 failed"];
|
||||
return;
|
||||
}
|
||||
|
||||
NSData* encServerChallengeResp = [Utils hexToBytes:[HttpManager getStringFromXML:challengeResp tag:@"challengeresponse"]];
|
||||
NSData* encServerChallengeResp = [Utils hexToBytes:[challengeResp parseStringTag:@"challengeresponse"]];
|
||||
NSData* decServerChallengeResp = [cryptoMan aesDecrypt:encServerChallengeResp withKey:aesKey];
|
||||
|
||||
NSData* serverResponse = [decServerChallengeResp subdataWithRange:NSMakeRange(0, 20)];
|
||||
@@ -83,50 +89,70 @@
|
||||
NSData* challengeRespHash = [cryptoMan SHA1HashData:[self concatData:[self concatData:serverChallenge with:[CryptoManager getSignatureFromCert:_cert]] with:clientSecret]];
|
||||
NSData* challengeRespEncrypted = [cryptoMan aesEncrypt:challengeRespHash withKey:aesKey];
|
||||
|
||||
NSData* secretResp = [_httpManager executeRequestSynchronously:[_httpManager newChallengeRespRequest:challengeRespEncrypted]];
|
||||
pairedString = [HttpManager getStringFromXML:secretResp tag:@"paired"];
|
||||
if (pairedString == NULL || ![pairedString isEqualToString:@"1"]) {
|
||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||
HttpResponse* secretResp = [_httpManager executeRequestSynchronously:[_httpManager newChallengeRespRequest:challengeRespEncrypted]];
|
||||
if (![self verifyResponseStatus:secretResp]) {
|
||||
return;
|
||||
}
|
||||
if (![secretResp parseIntTag:@"paired" value:pairedStatus] || !pairedStatus) {
|
||||
[_httpManager executeRequest:[_httpManager newUnpairRequest]];
|
||||
[_callback pairFailed:@"Pairing stage #3 failed"];
|
||||
return;
|
||||
}
|
||||
|
||||
NSData* serverSecretResp = [Utils hexToBytes:[HttpManager getStringFromXML:secretResp tag:@"pairingsecret"]];
|
||||
NSData* serverSecretResp = [Utils hexToBytes:[secretResp parseStringTag:@"pairingsecret"]];
|
||||
NSData* serverSecret = [serverSecretResp subdataWithRange:NSMakeRange(0, 16)];
|
||||
NSData* serverSignature = [serverSecretResp subdataWithRange:NSMakeRange(16, 256)];
|
||||
|
||||
if (![cryptoMan verifySignature:serverSecret withSignature:serverSignature andCert:[Utils hexToBytes:plainCert]]) {
|
||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||
[_httpManager executeRequest:[_httpManager newUnpairRequest]];
|
||||
[_callback pairFailed:@"Server certificate invalid"];
|
||||
return;
|
||||
}
|
||||
|
||||
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]];
|
||||
[_httpManager executeRequest:[_httpManager newUnpairRequest]];
|
||||
[_callback pairFailed:@"Incorrect PIN"];
|
||||
return;
|
||||
}
|
||||
|
||||
NSData* clientPairingSecret = [self concatData:clientSecret with:[cryptoMan signData:clientSecret withKey:[CryptoManager readKeyFromFile]]];
|
||||
NSData* clientSecretResp = [_httpManager executeRequestSynchronously:[_httpManager newClientSecretRespRequest:[Utils bytesToHex:clientPairingSecret]]];
|
||||
pairedString = [HttpManager getStringFromXML:clientSecretResp tag:@"paired"];
|
||||
if (pairedString == NULL || ![pairedString isEqualToString:@"1"]) {
|
||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||
HttpResponse* clientSecretResp = [_httpManager executeRequestSynchronously:[_httpManager newClientSecretRespRequest:[Utils bytesToHex:clientPairingSecret]]];
|
||||
if (![self verifyResponseStatus:clientSecretResp]) {
|
||||
return;
|
||||
}
|
||||
if ([clientSecretResp parseIntTag:@"paired" value:pairedStatus] || !pairedStatus) {
|
||||
[_httpManager executeRequest:[_httpManager newUnpairRequest]];
|
||||
[_callback pairFailed:@"Pairing stage #4 failed"];
|
||||
return;
|
||||
}
|
||||
|
||||
NSData* clientPairChallenge = [_httpManager executeRequestSynchronously:[_httpManager newPairChallenge]];
|
||||
pairedString = [HttpManager getStringFromXML:clientPairChallenge tag:@"paired"];
|
||||
if (pairedString == NULL || ![pairedString isEqualToString:@"1"]) {
|
||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||
HttpResponse* clientPairChallengeResp = [_httpManager executeRequestSynchronously:[_httpManager newPairChallenge]];
|
||||
if (![self verifyResponseStatus:clientPairChallengeResp]) {
|
||||
return;
|
||||
}
|
||||
if (![clientPairChallengeResp parseIntTag:@"paired" value:pairedStatus] || !pairedStatus) {
|
||||
[_httpManager executeRequest:[_httpManager newUnpairRequest]];
|
||||
[_callback pairFailed:@"Pairing stage #5 failed"];
|
||||
return;
|
||||
}
|
||||
[_callback pairSuccessful];
|
||||
}
|
||||
|
||||
- (BOOL) verifyResponseStatus:(HttpResponse*)resp {
|
||||
if (resp == nil) {
|
||||
[_httpManager executeRequest:[_httpManager newUnpairRequest]];
|
||||
[_callback pairFailed:@"Network error occured."];
|
||||
return false;
|
||||
} else if (![resp isStatusOk]) {
|
||||
[_httpManager executeRequest:[_httpManager newUnpairRequest]];
|
||||
[_callback pairFailed:resp.statusMessage];
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSData*) concatData:(NSData*)data with:(NSData*)moreData {
|
||||
NSMutableData* concatData = [[NSMutableData alloc] initWithData:data];
|
||||
[concatData appendData:moreData];
|
||||
|
||||
@@ -41,11 +41,11 @@
|
||||
deviceName:@"roth"
|
||||
cert:cert];
|
||||
|
||||
NSData* serverInfoResp = [hMan executeRequestSynchronously:[hMan newServerInfoRequest]];
|
||||
NSString* currentGame = [HttpManager getStringFromXML:serverInfoResp tag:@"currentgame"];
|
||||
NSString* pairStatus = [HttpManager getStringFromXML:serverInfoResp tag:@"PairStatus"];
|
||||
NSString* currentClient = [HttpManager getStringFromXML:serverInfoResp tag:@"CurrentClient"];
|
||||
if (currentGame == NULL || pairStatus == NULL) {
|
||||
HttpResponse* serverInfoResp = [hMan executeRequestSynchronously:[hMan newServerInfoRequest]];
|
||||
NSString* currentGame = [serverInfoResp parseStringTag:@"currentgame"];
|
||||
NSString* pairStatus = [serverInfoResp parseStringTag:@"PairStatus"];
|
||||
NSString* currentClient = [serverInfoResp parseStringTag:@"CurrentClient"];
|
||||
if (![serverInfoResp isStatusOk] || currentGame == NULL || pairStatus == NULL) {
|
||||
[_callbacks launchFailed:@"Failed to connect to PC"];
|
||||
return;
|
||||
}
|
||||
@@ -102,19 +102,21 @@
|
||||
}
|
||||
|
||||
- (BOOL) launchApp:(HttpManager*)hMan {
|
||||
NSData* launchResp = [hMan executeRequestSynchronously:
|
||||
HttpResponse* launchResp = [hMan executeRequestSynchronously:
|
||||
[hMan newLaunchRequest:_config.appID
|
||||
width:_config.width
|
||||
height:_config.height
|
||||
refreshRate:_config.frameRate
|
||||
rikey:[Utils bytesToHex:_config.riKey]
|
||||
rikeyid:_config.riKeyId]];
|
||||
NSString *gameSession = [HttpManager getStringFromXML:launchResp tag:@"gamesession"];
|
||||
if (launchResp == NULL) {
|
||||
NSString *gameSession = [launchResp parseStringTag:@"gamesession"];
|
||||
if (launchResp == NULL || ![launchResp isStatusOk]) {
|
||||
[_callbacks launchFailed:@"Failed to launch app"];
|
||||
NSLog(@"Failed Launch Response: %@", launchResp.statusMessage);
|
||||
return FALSE;
|
||||
} else if (gameSession == NULL || [gameSession isEqualToString:@"0"]) {
|
||||
[_callbacks launchFailed:[HttpManager getStatusStringFromXML:launchResp]];
|
||||
[_callbacks launchFailed:launchResp.statusMessage];
|
||||
NSLog(@"Failed to parse game session. Code: %ld Response: %@", (long)launchResp.statusCode, launchResp.statusMessage);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -122,15 +124,17 @@
|
||||
}
|
||||
|
||||
- (BOOL) resumeApp:(HttpManager*)hMan {
|
||||
NSData* resumeResp = [hMan executeRequestSynchronously:
|
||||
HttpResponse* resumeResp = [hMan executeRequestSynchronously:
|
||||
[hMan newResumeRequestWithRiKey:[Utils bytesToHex:_config.riKey]
|
||||
riKeyId:_config.riKeyId]];
|
||||
NSString *resume = [HttpManager getStringFromXML:resumeResp tag:@"resume"];
|
||||
if (resumeResp == NULL) {
|
||||
NSString* resume = [resumeResp parseStringTag:@"resume"];
|
||||
if (resumeResp == NULL || ![resumeResp isStatusOk]) {
|
||||
[_callbacks launchFailed:@"Failed to resume app"];
|
||||
NSLog(@"Failed Resume Response: %@", resumeResp.statusMessage);
|
||||
return FALSE;
|
||||
} else if (resume == NULL || [resume isEqualToString:@"0"]) {
|
||||
[_callbacks launchFailed:[HttpManager getStatusStringFromXML:resumeResp]];
|
||||
[_callbacks launchFailed:resumeResp.statusMessage];
|
||||
NSLog(@"Failed to parse resume response. Code: %ld Response: %@", (long)resumeResp.statusCode, resumeResp.statusMessage);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -69,18 +69,25 @@ static StreamConfiguration* streamConfig;
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
_computerNameButton.title = _selectedHost.name;
|
||||
[self.navigationController.navigationBar setNeedsLayout];
|
||||
[self.navigationController.navigationBar setNeedsLayout];
|
||||
});
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:_selectedHost.address uniqueId:_uniqueId deviceName:deviceName cert:_cert];
|
||||
NSData* appListResp = [hMan executeRequestSynchronously:[hMan newAppListRequest]];
|
||||
appList = [HttpManager getAppListFromXML:appListResp];
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self updateApps];
|
||||
});
|
||||
|
||||
[_appManager stopRetrieving];
|
||||
[_appManager retrieveAssets:appList fromHost:_selectedHost];
|
||||
HttpResponse* appListResp = [hMan executeRequestSynchronously:[hMan newAppListRequest]];
|
||||
if (appListResp == nil || ![appListResp isStatusOk]) {
|
||||
NSLog(@"Failed to get applist: %@", appListResp.statusMessage);
|
||||
} else {
|
||||
appList = [appListResp getAppList];
|
||||
if (appList == nil) {
|
||||
NSLog(@"Failed to parse applist");
|
||||
} else {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self updateApps];
|
||||
});
|
||||
|
||||
[_appManager stopRetrieving];
|
||||
[_appManager retrieveAssets:appList fromHost:_selectedHost];
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -108,16 +115,20 @@ static StreamConfiguration* streamConfig;
|
||||
_selectedHost = host;
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:host.address uniqueId:_uniqueId deviceName:deviceName cert:_cert];
|
||||
NSData* serverInfoResp = [hMan executeRequestSynchronously:[hMan newServerInfoRequest]];
|
||||
if ([[HttpManager getStringFromXML:serverInfoResp tag:@"PairStatus"] isEqualToString:@"1"]) {
|
||||
NSLog(@"Already Paired");
|
||||
[self alreadyPaired];
|
||||
HttpResponse* serverInfoResp = [hMan executeRequestSynchronously:[hMan newServerInfoRequest]];
|
||||
if (serverInfoResp == nil || ![serverInfoResp isStatusOk]) {
|
||||
NSLog(@"Failed to get server info: %@", serverInfoResp.statusMessage);
|
||||
} else {
|
||||
NSLog(@"Trying to pair");
|
||||
// Polling the server while pairing causes the server to screw up
|
||||
[_discMan stopDiscoveryBlocking];
|
||||
PairManager* pMan = [[PairManager alloc] initWithManager:hMan andCert:_cert callback:self];
|
||||
[_opQueue addOperation:pMan];
|
||||
if ([[serverInfoResp parseStringTag:@"PairStatus"] isEqualToString:@"1"]) {
|
||||
NSLog(@"Already Paired");
|
||||
[self alreadyPaired];
|
||||
} else {
|
||||
NSLog(@"Trying to pair");
|
||||
// Polling the server while pairing causes the server to screw up
|
||||
[_discMan stopDiscoveryBlocking];
|
||||
PairManager* pMan = [[PairManager alloc] initWithManager:hMan andCert:_cert callback:self];
|
||||
[_opQueue addOperation:pMan];
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -163,7 +174,7 @@ static StreamConfiguration* streamConfig;
|
||||
|
||||
// these two lines are required for iPad support of UIAlertSheet
|
||||
longClickAlert.popoverPresentationController.sourceView = view;
|
||||
|
||||
|
||||
longClickAlert.popoverPresentationController.sourceRect = CGRectMake(view.bounds.size.width / 2.0, view.bounds.size.height / 2.0, 1.0, 1.0); // center of the view
|
||||
[self presentViewController:longClickAlert animated:YES completion:^{
|
||||
[self updateHosts];
|
||||
@@ -227,29 +238,29 @@ static StreamConfiguration* streamConfig;
|
||||
App* currentApp = [self findRunningApp];
|
||||
if (currentApp != nil) {
|
||||
UIAlertController* alertController = [UIAlertController
|
||||
alertControllerWithTitle: app.appName
|
||||
message: [app.appId isEqualToString:currentApp.appId] ? @"" : [NSString stringWithFormat:@"%@ is currently running", currentApp.appName]preferredStyle:UIAlertControllerStyleAlert];
|
||||
alertControllerWithTitle: app.appName
|
||||
message: [app.appId isEqualToString:currentApp.appId] ? @"" : [NSString stringWithFormat:@"%@ is currently running", currentApp.appName]preferredStyle:UIAlertControllerStyleAlert];
|
||||
[alertController addAction:[UIAlertAction
|
||||
actionWithTitle:[app.appId isEqualToString:currentApp.appId] ? @"Resume App" : @"Resume Running App" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){
|
||||
NSLog(@"Resuming application: %@", currentApp.appName);
|
||||
[self performSegueWithIdentifier:@"createStreamFrame" sender:nil];
|
||||
}]];
|
||||
actionWithTitle:[app.appId isEqualToString:currentApp.appId] ? @"Resume App" : @"Resume Running App" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){
|
||||
NSLog(@"Resuming application: %@", currentApp.appName);
|
||||
[self performSegueWithIdentifier:@"createStreamFrame" sender:nil];
|
||||
}]];
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:
|
||||
[app.appId isEqualToString:currentApp.appId] ? @"Quit App" : @"Quit Running App and Start" style:UIAlertActionStyleDestructive handler:^(UIAlertAction* action){
|
||||
NSLog(@"Quitting application: %@", currentApp.appName);
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:_selectedHost.address uniqueId:_uniqueId deviceName:deviceName cert:_cert];
|
||||
[hMan executeRequestSynchronously:[hMan newQuitAppRequest]];
|
||||
// TODO: handle failure to quit app
|
||||
currentApp.isRunning = NO;
|
||||
|
||||
if (![app.appId isEqualToString:currentApp.appId]) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self performSegueWithIdentifier:@"createStreamFrame" sender:nil];
|
||||
});
|
||||
}
|
||||
});
|
||||
}]];
|
||||
[app.appId isEqualToString:currentApp.appId] ? @"Quit App" : @"Quit Running App and Start" style:UIAlertActionStyleDestructive handler:^(UIAlertAction* action){
|
||||
NSLog(@"Quitting application: %@", currentApp.appName);
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:_selectedHost.address uniqueId:_uniqueId deviceName:deviceName cert:_cert];
|
||||
[hMan executeRequestSynchronously:[hMan newQuitAppRequest]];
|
||||
// TODO: handle failure to quit app
|
||||
currentApp.isRunning = NO;
|
||||
|
||||
if (![app.appId isEqualToString:currentApp.appId]) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self performSegueWithIdentifier:@"createStreamFrame" sender:nil];
|
||||
});
|
||||
}
|
||||
});
|
||||
}]];
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]];
|
||||
[self presentViewController:alertController animated:YES completion:nil];
|
||||
} else {
|
||||
@@ -344,7 +355,7 @@ static StreamConfiguration* streamConfig;
|
||||
[super viewDidDisappear:animated];
|
||||
// when discovery stops, we must create a new instance because you cannot restart an NSOperation when it is finished
|
||||
[_discMan stopDiscovery];
|
||||
|
||||
|
||||
// In case the host objects were updated in the background
|
||||
[[[DataManager alloc] init] saveHosts];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user