From 286b19d3601e84dba68be8e8c45018edcd0db3cb Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Mon, 10 Aug 2020 22:56:47 -0700 Subject: [PATCH] Add automatic network testing on connection failure --- Limelight/Stream/Connection.h | 4 +- Limelight/Stream/Connection.m | 2 +- .../ViewControllers/MainFrameViewController.m | 6 +++ .../StreamFrameViewController.m | 49 ++++++++++++------- 4 files changed, 42 insertions(+), 19 deletions(-) diff --git a/Limelight/Stream/Connection.h b/Limelight/Stream/Connection.h index 1cddc2d5..8e7438c3 100644 --- a/Limelight/Stream/Connection.h +++ b/Limelight/Stream/Connection.h @@ -9,13 +9,15 @@ #import "VideoDecoderRenderer.h" #import "StreamConfiguration.h" +#define CONN_TEST_SERVER "ios.conntest.moonlight-stream.org" + @protocol ConnectionCallbacks - (void) connectionStarted; - (void) connectionTerminated:(int)errorCode; - (void) stageStarting:(const char*)stageName; - (void) stageComplete:(const char*)stageName; -- (void) stageFailed:(const char*)stageName withError:(int)errorCode; +- (void) stageFailed:(const char*)stageName withError:(int)errorCode portTestFlags:(int)portTestFlags; - (void) launchFailed:(NSString*)message; - (void) rumble:(unsigned short)controllerNumber lowFreqMotor:(unsigned short)lowFreqMotor highFreqMotor:(unsigned short)highFreqMotor; - (void) connectionStatusUpdate:(int)status; diff --git a/Limelight/Stream/Connection.m b/Limelight/Stream/Connection.m index 90238b8d..86160dc4 100644 --- a/Limelight/Stream/Connection.m +++ b/Limelight/Stream/Connection.m @@ -268,7 +268,7 @@ void ClStageComplete(int stage) void ClStageFailed(int stage, int errorCode) { - [_callbacks stageFailed:LiGetStageName(stage) withError:errorCode]; + [_callbacks stageFailed:LiGetStageName(stage) withError:errorCode portTestFlags:LiGetPortFlagsFromStage(stage)]; } void ClConnectionStarted(void) diff --git a/Limelight/ViewControllers/MainFrameViewController.m b/Limelight/ViewControllers/MainFrameViewController.m index f264fea6..06867e43 100644 --- a/Limelight/ViewControllers/MainFrameViewController.m +++ b/Limelight/ViewControllers/MainFrameViewController.m @@ -509,6 +509,12 @@ static NSMutableSet* hostList; [self updateHosts]; }); } else { + unsigned int portTestResults = LiTestClientConnectivity(CONN_TEST_SERVER, 443, + ML_PORT_FLAG_TCP_47984 | ML_PORT_FLAG_TCP_47989); + if (portTestResults != ML_TEST_RESULT_INCONCLUSIVE && portTestResults != 0) { + error = [error stringByAppendingString:@"\n\nYour device's Internet connection is blocking Moonlight. Streaming over the Internet may not work while connected to this network."]; + } + UIAlertController* hostNotFoundAlert = [UIAlertController alertControllerWithTitle:@"Add Host Manually" message:error preferredStyle:UIAlertControllerStyleAlert]; [Utils addHelpOptionToDialog:hostNotFoundAlert]; [hostNotFoundAlert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]]; diff --git a/Limelight/ViewControllers/StreamFrameViewController.m b/Limelight/ViewControllers/StreamFrameViewController.m index a85d8ab1..0edd14d3 100644 --- a/Limelight/ViewControllers/StreamFrameViewController.m +++ b/Limelight/ViewControllers/StreamFrameViewController.m @@ -233,6 +233,9 @@ - (void)connectionTerminated:(int)errorCode { Log(LOG_I, @"Connection terminated: %d", errorCode); + unsigned int portTestResults = LiTestClientConnectivity(CONN_TEST_SERVER, 443, + LiGetPortFlagsFromTerminationErrorCode(errorCode)); + dispatch_async(dispatch_get_main_queue(), ^{ // Allow the display to go to sleep now [UIApplication sharedApplication].idleTimerDisabled = NO; @@ -240,20 +243,26 @@ NSString* title; NSString* message; - switch (errorCode) { - case ML_ERROR_GRACEFUL_TERMINATION: - [self returnToMainFrame]; - return; - - case ML_ERROR_NO_VIDEO_TRAFFIC: - title = @"Connection Error"; - message = @"No video received from host. Check the host PC's firewall and port forwarding rules."; - break; - - default: - title = @"Connection Terminated"; - message = @"The connection was terminated"; - break; + if (portTestResults != ML_TEST_RESULT_INCONCLUSIVE && portTestResults != 0) { + title = @"Connection Error"; + message = @"Your device's Internet connection is blocking Moonlight. Streaming over the Internet may not work while connected to this network."; + } + else { + switch (errorCode) { + case ML_ERROR_GRACEFUL_TERMINATION: + [self returnToMainFrame]; + return; + + case ML_ERROR_NO_VIDEO_TRAFFIC: + title = @"Connection Error"; + message = @"No video received from host. Check the host PC's firewall and port forwarding rules."; + break; + + default: + title = @"Connection Terminated"; + message = @"The connection was terminated"; + break; + } } UIAlertController* conTermAlert = [UIAlertController alertControllerWithTitle:title @@ -283,16 +292,22 @@ - (void) stageComplete:(const char*)stageName { } -- (void) stageFailed:(const char*)stageName withError:(int)errorCode { +- (void) stageFailed:(const char*)stageName withError:(int)errorCode portTestFlags:(int)portTestFlags { Log(LOG_I, @"Stage %s failed: %d", stageName, errorCode); + + unsigned int portTestResults = LiTestClientConnectivity(CONN_TEST_SERVER, 443, portTestFlags); dispatch_async(dispatch_get_main_queue(), ^{ // Allow the display to go to sleep now [UIApplication sharedApplication].idleTimerDisabled = NO; + NSString* message = [NSString stringWithFormat:@"%s failed with error %d", stageName, errorCode]; + if (portTestResults != ML_TEST_RESULT_INCONCLUSIVE && portTestResults != 0) { + message = [message stringByAppendingString:@"\n\nYour device's Internet connection is blocking Moonlight. Streaming over the Internet may not work while connected to this network."]; + } + UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"Connection Failed" - message:[NSString stringWithFormat:@"%s failed with error %d", - stageName, errorCode] + message:message preferredStyle:UIAlertControllerStyleAlert]; [Utils addHelpOptionToDialog:alert]; [alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){