diff --git a/Limelight/Network/ConnectionHelper.m b/Limelight/Network/ConnectionHelper.m index bb415395..e0c3e509 100644 --- a/Limelight/Network/ConnectionHelper.m +++ b/Limelight/Network/ConnectionHelper.m @@ -18,11 +18,11 @@ HttpManager* hMan = [[HttpManager alloc] initWithHost:hostIP uniqueId:uniqueId serverCert:cert]; // Try up to 5 times to get the app list - AppListResponse* appListResp; + AppListResponse* appListResp = nil; for (int i = 0; i < 5; i++) { appListResp = [[AppListResponse alloc] init]; [hMan executeRequestSynchronously:[HttpRequest requestForResponse:appListResp withUrlRequest:[hMan newAppListRequest]]]; - if (appListResp == nil || ![appListResp isStatusOk] || [appListResp getAppList] == nil) { + if (![appListResp isStatusOk] || [appListResp getAppList] == nil) { Log(LOG_W, @"Failed to get applist on try %d: %@", i, appListResp.statusMessage); // Wait for one second then retry @@ -30,10 +30,11 @@ } else { Log(LOG_I, @"App list successfully retreived - took %d tries", i); - return appListResp; + break; } } - return nil; + + return appListResp; } @end diff --git a/Limelight/Network/PairManager.m b/Limelight/Network/PairManager.m index 19641f5a..718ae150 100644 --- a/Limelight/Network/PairManager.m +++ b/Limelight/Network/PairManager.m @@ -33,10 +33,6 @@ ServerInfoResponse* serverInfoResp = [[ServerInfoResponse alloc] init]; [_httpManager executeRequestSynchronously:[HttpRequest requestForResponse:serverInfoResp withUrlRequest:[_httpManager newServerInfoRequest:false] fallbackError:401 fallbackRequest:[_httpManager newHttpServerInfoRequest]]]; - if (serverInfoResp == nil) { - [_callback pairFailed:@"Unable to connect to PC"]; - return; - } if ([serverInfoResp isStatusOk]) { if ([[serverInfoResp getStringTag:@"state"] hasSuffix:@"_SERVER_BUSY"]) { [_callback pairFailed:@"You cannot pair while a previous session is still running on the host PC. Quit any running games or reboot the host PC, then try pairing again."]; @@ -51,13 +47,25 @@ [_callback alreadyPaired]; } } + else { + [_callback pairFailed:serverInfoResp.statusMessage]; + } } -- (void) finishPairing:(UIBackgroundTaskIdentifier)bgId withError:(NSString*)errorMsg { +- (void) finishPairing:(UIBackgroundTaskIdentifier)bgId + forResponse:(HttpResponse*)resp + withFallbackError:(NSString*)errorMsg { + [_httpManager executeRequestSynchronously:[HttpRequest requestWithUrlRequest:[_httpManager newUnpairRequest]]]; + if (bgId != UIBackgroundTaskInvalid) { [[UIApplication sharedApplication] endBackgroundTask:bgId]; } + if (![resp isStatusOk]) { + // Use the response error if the request failed + errorMsg = resp.statusMessage; + } + [_callback pairFailed:errorMsg]; } @@ -87,18 +95,13 @@ HttpResponse* pairResp = [[HttpResponse alloc] init]; [_httpManager executeRequestSynchronously:[HttpRequest requestForResponse:pairResp withUrlRequest:[_httpManager newPairRequest:salt clientCert:_clientCert]]]; if (![self verifyResponseStatus:pairResp]) { - [self finishPairing:bgId withError:@"Pairing stage #1 failed"]; - return; - } - NSInteger pairedStatus; - if (![pairResp getIntTag:@"paired" value:&pairedStatus] || !pairedStatus) { - [self finishPairing:bgId withError:@"Pairing was declined by the target."]; + [self finishPairing:bgId forResponse:pairResp withFallbackError:@"Pairing was declined by the target."]; return; } NSString* plainCert = [pairResp getStringTag:@"plaincert"]; if ([plainCert length] == 0) { - [self finishPairing:bgId withError:@"Another pairing attempt is already in progress."]; + [self finishPairing:bgId forResponse:pairResp withFallbackError:@"Another pairing attempt is already in progress."]; return; } @@ -125,11 +128,8 @@ HttpResponse* challengeResp = [[HttpResponse alloc] init]; [_httpManager executeRequestSynchronously:[HttpRequest requestForResponse:challengeResp withUrlRequest:[_httpManager newChallengeRequest:encryptedChallenge]]]; - if (![self verifyResponseStatus:challengeResp] || - ![challengeResp getIntTag:@"paired" value:&pairedStatus] || - pairedStatus != 1) { - [_httpManager executeRequestSynchronously:[HttpRequest requestWithUrlRequest:[_httpManager newUnpairRequest]]]; - [self finishPairing:bgId withError:@"Pairing stage #2 failed"]; + if (![self verifyResponseStatus:challengeResp]) { + [self finishPairing:bgId forResponse:challengeResp withFallbackError:@"Pairing stage #2 failed"]; return; } @@ -152,11 +152,8 @@ HttpResponse* secretResp = [[HttpResponse alloc] init]; [_httpManager executeRequestSynchronously:[HttpRequest requestForResponse:secretResp withUrlRequest:[_httpManager newChallengeRespRequest:challengeRespEncrypted]]]; - if (![self verifyResponseStatus:secretResp] || - ![secretResp getIntTag:@"paired" value:&pairedStatus] || - pairedStatus != 1) { - [_httpManager executeRequestSynchronously:[HttpRequest requestWithUrlRequest:[_httpManager newUnpairRequest]]]; - [self finishPairing:bgId withError:@"Pairing stage #3 failed"]; + if (![self verifyResponseStatus:secretResp]) { + [self finishPairing:bgId forResponse:secretResp withFallbackError:@"Pairing stage #3 failed"]; return; } @@ -165,8 +162,7 @@ NSData* serverSignature = [serverSecretResp subdataWithRange:NSMakeRange(16, 256)]; if (![cryptoMan verifySignature:serverSecret withSignature:serverSignature andCert:[Utils hexToBytes:plainCert]]) { - [_httpManager executeRequestSynchronously:[HttpRequest requestWithUrlRequest:[_httpManager newUnpairRequest]]]; - [self finishPairing:bgId withError:@"Server certificate invalid"]; + [self finishPairing:bgId forResponse:secretResp withFallbackError:@"Server certificate invalid"]; return; } @@ -179,29 +175,22 @@ serverChallengeRespHash = [cryptoMan SHA1HashData: serverChallengeRespHashInput]; } if (![serverChallengeRespHash isEqual:serverResponse]) { - [_httpManager executeRequestSynchronously:[HttpRequest requestWithUrlRequest:[_httpManager newUnpairRequest]]]; - [self finishPairing:bgId withError:@"Incorrect PIN"]; + [self finishPairing:bgId forResponse:secretResp withFallbackError:@"Incorrect PIN"]; return; } NSData* clientPairingSecret = [self concatData:clientSecret with:[cryptoMan signData:clientSecret withKey:[CryptoManager readKeyFromFile]]]; HttpResponse* clientSecretResp = [[HttpResponse alloc] init]; [_httpManager executeRequestSynchronously:[HttpRequest requestForResponse:clientSecretResp withUrlRequest:[_httpManager newClientSecretRespRequest:[Utils bytesToHex:clientPairingSecret]]]]; - if (![self verifyResponseStatus:clientSecretResp] || - ![clientSecretResp getIntTag:@"paired" value:&pairedStatus] || - pairedStatus != 1) { - [_httpManager executeRequestSynchronously:[HttpRequest requestWithUrlRequest:[_httpManager newUnpairRequest]]]; - [self finishPairing:bgId withError:@"Pairing stage #4 failed"]; + if (![self verifyResponseStatus:clientSecretResp]) { + [self finishPairing:bgId forResponse:clientSecretResp withFallbackError:@"Pairing stage #4 failed"]; return; } HttpResponse* clientPairChallengeResp = [[HttpResponse alloc] init]; [_httpManager executeRequestSynchronously:[HttpRequest requestForResponse:clientPairChallengeResp withUrlRequest:[_httpManager newPairChallenge]]]; - if (![self verifyResponseStatus:clientPairChallengeResp] || - ![clientPairChallengeResp getIntTag:@"paired" value:&pairedStatus] || - pairedStatus != 1) { - [_httpManager executeRequestSynchronously:[HttpRequest requestWithUrlRequest:[_httpManager newUnpairRequest]]]; - [self finishPairing:bgId withError:@"Pairing stage #5 failed"]; + if (![self verifyResponseStatus:clientPairChallengeResp]) { + [self finishPairing:bgId forResponse:clientPairChallengeResp withFallbackError:@"Pairing stage #5 failed"]; return; } @@ -210,14 +199,16 @@ // Caller calls finishPairing for us on failure - (BOOL) verifyResponseStatus:(HttpResponse*)resp { - if (resp == nil) { - [_httpManager executeRequestSynchronously:[HttpRequest requestWithUrlRequest:[_httpManager newUnpairRequest]]]; - return false; - } else if (![resp isStatusOk]) { - [_httpManager executeRequestSynchronously:[HttpRequest requestWithUrlRequest:[_httpManager newUnpairRequest]]]; + if (![resp isStatusOk]) { return false; } else { - return true; + long pairedStatus; + + if (![resp getIntTag:@"paired" value:&pairedStatus]) { + return false; + } + + return pairedStatus == 1; } } diff --git a/Limelight/Stream/StreamManager.m b/Limelight/Stream/StreamManager.m index 0eaa5e75..6008f50c 100644 --- a/Limelight/Stream/StreamManager.m +++ b/Limelight/Stream/StreamManager.m @@ -50,7 +50,11 @@ NSString* appversion = [serverInfoResp getStringTag:@"appversion"]; NSString* gfeVersion = [serverInfoResp getStringTag:@"GfeVersion"]; NSString* serverState = [serverInfoResp getStringTag:@"state"]; - if (![serverInfoResp isStatusOk] || pairStatus == NULL || appversion == NULL || serverState == NULL) { + if (![serverInfoResp isStatusOk]) { + [_callbacks launchFailed:serverInfoResp.statusMessage]; + return; + } + else if (pairStatus == NULL || appversion == NULL || serverState == NULL) { [_callbacks launchFailed:@"Failed to connect to PC"]; return; } diff --git a/Limelight/ViewControllers/MainFrameViewController.m b/Limelight/ViewControllers/MainFrameViewController.m index 5c8633fc..0eb5ee69 100644 --- a/Limelight/ViewControllers/MainFrameViewController.m +++ b/Limelight/ViewControllers/MainFrameViewController.m @@ -152,7 +152,7 @@ static NSMutableSet* hostList; [self->_discMan addHostToDiscovery:host]; - if (appListResp == nil || ![appListResp isStatusOk] || [appListResp getAppList] == nil) { + if (![appListResp isStatusOk] || [appListResp getAppList] == nil) { Log(LOG_W, @"Failed to get applist: %@", appListResp.statusMessage); dispatch_async(dispatch_get_main_queue(), ^{ if (host != self->_selectedHost) { @@ -160,8 +160,8 @@ static NSMutableSet* hostList; return; } - UIAlertController* applistAlert = [UIAlertController alertControllerWithTitle:@"Fetching App List Failed" - message:@"The connection to the PC was interrupted." + UIAlertController* applistAlert = [UIAlertController alertControllerWithTitle:@"Connection Interrupted" + message:appListResp.statusMessage preferredStyle:UIAlertControllerStyleAlert]; [Utils addHelpOptionToDialog:applistAlert]; [applistAlert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]]; @@ -320,7 +320,7 @@ static NSMutableSet* hostList; fallbackError:401 fallbackRequest:[hMan newHttpServerInfoRequest]]]; [self->_discMan addHostToDiscovery:host]; - if (serverInfoResp == nil || ![serverInfoResp isStatusOk]) { + if (![serverInfoResp isStatusOk]) { Log(LOG_W, @"Failed to get server info: %@", serverInfoResp.statusMessage); dispatch_async(dispatch_get_main_queue(), ^{ if (host != self->_selectedHost) { @@ -328,8 +328,8 @@ static NSMutableSet* hostList; return; } - UIAlertController* applistAlert = [UIAlertController alertControllerWithTitle:@"Fetching Server Info Failed" - message:@"The connection to the PC was interrupted." + UIAlertController* applistAlert = [UIAlertController alertControllerWithTitle:@"Connection Failed" + message:serverInfoResp.statusMessage preferredStyle:UIAlertControllerStyleAlert]; [Utils addHelpOptionToDialog:applistAlert]; [applistAlert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];