mirror of
https://github.com/moonlight-stream/moonlight-ios.git
synced 2026-10-25 13:31:47 +00:00
Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6273f2bb29 | ||
|
|
fac48ecf42 | ||
|
|
b5bf26bb2d | ||
|
|
00fab87b4c | ||
|
|
3554b40962 | ||
|
|
aa3752a905 | ||
|
|
47850cd658 | ||
|
|
1b98870b41 |
No files matched your search
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -21,7 +21,7 @@
|
|||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>5</string>
|
<string>7</string>
|
||||||
<key>LSApplicationCategoryType</key>
|
<key>LSApplicationCategoryType</key>
|
||||||
<string>public.app-category.games</string>
|
<string>public.app-category.games</string>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
@interface HttpManager : NSObject <NSURLConnectionDelegate, NSURLConnectionDataDelegate>
|
@interface HttpManager : NSObject <NSURLConnectionDelegate, NSURLConnectionDataDelegate>
|
||||||
|
|
||||||
+ (NSString*) getStringFromXML:(NSData*)xml tag:(NSString*)tag;
|
+ (NSString*) getStringFromXML:(NSData*)xml tag:(NSString*)tag;
|
||||||
|
+ (NSString*) getStatusStringFromXML:(NSData*)xml;
|
||||||
|
|
||||||
- (id) initWithHost:(NSString*) host uniqueId:(NSString*) uniqueId deviceName:(NSString*) deviceName cert:(NSData*) cert;
|
- (id) initWithHost:(NSString*) host uniqueId:(NSString*) uniqueId deviceName:(NSString*) deviceName cert:(NSData*) cert;
|
||||||
- (NSURLRequest*) newPairRequest:(NSData*)salt;
|
- (NSURLRequest*) newPairRequest:(NSData*)salt;
|
||||||
|
|||||||
@@ -25,6 +25,24 @@
|
|||||||
|
|
||||||
static const NSString* PORT = @"47984";
|
static const NSString* PORT = @"47984";
|
||||||
|
|
||||||
|
+ (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);
|
||||||
|
|
||||||
|
string = [HttpManager getStatusMessage: rootNode];
|
||||||
|
xmlFree(rootNode);
|
||||||
|
xmlFree(docPtr);
|
||||||
|
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
+ (NSString*) getStringFromXML:(NSData*)xml tag:(NSString*)tag {
|
+ (NSString*) getStringFromXML:(NSData*)xml tag:(NSString*)tag {
|
||||||
xmlDocPtr docPtr = xmlParseMemory([xml bytes], (int)[xml length]);
|
xmlDocPtr docPtr = xmlParseMemory([xml bytes], (int)[xml length]);
|
||||||
|
|
||||||
@@ -60,6 +78,13 @@ static const NSString* PORT = @"47984";
|
|||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (NSString*) getStatusMessage:(xmlNodePtr)docRoot {
|
||||||
|
xmlChar* statusMsgXml = xmlGetProp(docRoot, (const xmlChar*)"status_message");
|
||||||
|
NSString* statusMsg = [NSString stringWithUTF8String:(const char*)statusMsgXml];
|
||||||
|
xmlFree(statusMsgXml);
|
||||||
|
return statusMsg;
|
||||||
|
}
|
||||||
|
|
||||||
+ (bool) verifyStatus:(xmlNodePtr)docRoot {
|
+ (bool) verifyStatus:(xmlNodePtr)docRoot {
|
||||||
xmlChar* statusStr = xmlGetProp(docRoot, (const xmlChar*)"status_code");
|
xmlChar* statusStr = xmlGetProp(docRoot, (const xmlChar*)"status_code");
|
||||||
|
|||||||
@@ -28,12 +28,19 @@
|
|||||||
|
|
||||||
- (void) main {
|
- (void) main {
|
||||||
NSData* serverInfo = [_httpManager executeRequestSynchronously:[_httpManager newServerInfoRequest]];
|
NSData* serverInfo = [_httpManager executeRequestSynchronously:[_httpManager newServerInfoRequest]];
|
||||||
if (![[HttpManager getStringFromXML:serverInfo tag:@"PairStatus"] isEqual:@"1"]) {
|
if (serverInfo == NULL) {
|
||||||
|
[_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];
|
[self initiatePair];
|
||||||
} else {
|
} else {
|
||||||
[_callback pairFailed:@"Already Paired"];
|
[_callback pairFailed:@"This device is already paired."];
|
||||||
}
|
}
|
||||||
[_httpManager executeRequestSynchronously:[_httpManager newAppListRequest]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) initiatePair {
|
- (void) initiatePair {
|
||||||
@@ -47,8 +54,7 @@
|
|||||||
pairedString = [HttpManager getStringFromXML:pairResp tag:@"paired"];
|
pairedString = [HttpManager getStringFromXML:pairResp tag:@"paired"];
|
||||||
if (pairedString == NULL || ![pairedString isEqualToString:@"1"]) {
|
if (pairedString == NULL || ![pairedString isEqualToString:@"1"]) {
|
||||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||||
//TODO: better message
|
[_callback pairFailed:@"Pairing was declined by the target."];
|
||||||
[_callback pairFailed:@"pairResp failed"];
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,8 +70,7 @@
|
|||||||
pairedString = [HttpManager getStringFromXML:challengeResp tag:@"paired"];
|
pairedString = [HttpManager getStringFromXML:challengeResp tag:@"paired"];
|
||||||
if (pairedString == NULL || ![pairedString isEqualToString:@"1"]) {
|
if (pairedString == NULL || ![pairedString isEqualToString:@"1"]) {
|
||||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||||
//TODO: better message
|
[_callback pairFailed:@"Pairing stage #2 failed"];
|
||||||
[_callback pairFailed:@"challengeResp failed"];
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,8 +88,7 @@
|
|||||||
pairedString = [HttpManager getStringFromXML:secretResp tag:@"paired"];
|
pairedString = [HttpManager getStringFromXML:secretResp tag:@"paired"];
|
||||||
if (pairedString == NULL || ![pairedString isEqualToString:@"1"]) {
|
if (pairedString == NULL || ![pairedString isEqualToString:@"1"]) {
|
||||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||||
//TODO: better message
|
[_callback pairFailed:@"Pairing stage #3 failed"];
|
||||||
[_callback pairFailed:@"secretResp failed"];
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,16 +98,14 @@
|
|||||||
|
|
||||||
if (![cryptoMan verifySignature:serverSecret withSignature:serverSignature andCert:[Utils hexToBytes:plainCert]]) {
|
if (![cryptoMan verifySignature:serverSecret withSignature:serverSignature andCert:[Utils hexToBytes:plainCert]]) {
|
||||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||||
//TODO: better message
|
[_callback pairFailed:@"Server certificate invalid"];
|
||||||
[_callback pairFailed:@"verifySignature failed"];
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSData* serverChallengeRespHash = [cryptoMan SHA1HashData:[self concatData:[self concatData:randomChallenge with:[CryptoManager getSignatureFromCert:[Utils 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]) {
|
if (![serverChallengeRespHash isEqual:serverResponse]) {
|
||||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||||
//TODO: better message
|
[_callback pairFailed:@"Incorrect PIN"];
|
||||||
[_callback pairFailed:@"serverChallengeResp failed"];
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,8 +114,7 @@
|
|||||||
pairedString = [HttpManager getStringFromXML:clientSecretResp tag:@"paired"];
|
pairedString = [HttpManager getStringFromXML:clientSecretResp tag:@"paired"];
|
||||||
if (pairedString == NULL || ![pairedString isEqualToString:@"1"]) {
|
if (pairedString == NULL || ![pairedString isEqualToString:@"1"]) {
|
||||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||||
//TODO: better message
|
[_callback pairFailed:@"Pairing stage #4 failed"];
|
||||||
[_callback pairFailed:@"clientSecretResp failed"];
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,8 +122,7 @@
|
|||||||
pairedString = [HttpManager getStringFromXML:clientPairChallenge tag:@"paired"];
|
pairedString = [HttpManager getStringFromXML:clientPairChallenge tag:@"paired"];
|
||||||
if (pairedString == NULL || ![pairedString isEqualToString:@"1"]) {
|
if (pairedString == NULL || ![pairedString isEqualToString:@"1"]) {
|
||||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||||
//TODO: better message
|
[_callback pairFailed:@"Pairing stage #5 failed"];
|
||||||
[_callback pairFailed:@"clientPairChallenge failed"];
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
[_callback pairSuccessful];
|
[_callback pairSuccessful];
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
- (void) stageStarting:(char*)stageName;
|
- (void) stageStarting:(char*)stageName;
|
||||||
- (void) stageComplete:(char*)stageName;
|
- (void) stageComplete:(char*)stageName;
|
||||||
- (void) stageFailed:(char*)stageName withError:(long)errorCode;
|
- (void) stageFailed:(char*)stageName withError:(long)errorCode;
|
||||||
- (void) launchFailed;
|
- (void) launchFailed:(NSString*)message;
|
||||||
- (void) displayMessage:(char*)message;
|
- (void) displayMessage:(char*)message;
|
||||||
- (void) displayTransientMessage:(char*)message;
|
- (void) displayTransientMessage:(char*)message;
|
||||||
|
|
||||||
|
|||||||
@@ -43,27 +43,25 @@
|
|||||||
NSString* currentGame = [HttpManager getStringFromXML:serverInfoResp tag:@"currentgame"];
|
NSString* currentGame = [HttpManager getStringFromXML:serverInfoResp tag:@"currentgame"];
|
||||||
NSString* pairStatus = [HttpManager getStringFromXML:serverInfoResp tag:@"PairStatus"];
|
NSString* pairStatus = [HttpManager getStringFromXML:serverInfoResp tag:@"PairStatus"];
|
||||||
if (currentGame == NULL || pairStatus == NULL) {
|
if (currentGame == NULL || pairStatus == NULL) {
|
||||||
[_callbacks launchFailed];
|
[_callbacks launchFailed:@"Failed to connect to PC"];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (![pairStatus isEqualToString:@"1"]) {
|
if (![pairStatus isEqualToString:@"1"]) {
|
||||||
// Not paired
|
// Not paired
|
||||||
// TODO: Display better error message
|
[_callbacks launchFailed:@"Device not paired to PC"];
|
||||||
[_callbacks launchFailed];
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// resumeApp and launchApp handle calling launchFailed
|
||||||
if (![currentGame isEqualToString:@"0"]) {
|
if (![currentGame isEqualToString:@"0"]) {
|
||||||
// App already running, resume it
|
// App already running, resume it
|
||||||
if (![self resumeApp:hMan]) {
|
if (![self resumeApp:hMan]) {
|
||||||
[_callbacks launchFailed];
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Start app
|
// Start app
|
||||||
if (![self launchApp:hMan]) {
|
if (![self launchApp:hMan]) {
|
||||||
[_callbacks launchFailed];
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,7 +86,11 @@
|
|||||||
rikey:[Utils bytesToHex:_config.riKey]
|
rikey:[Utils bytesToHex:_config.riKey]
|
||||||
rikeyid:_config.riKeyId]];
|
rikeyid:_config.riKeyId]];
|
||||||
NSString *gameSession = [HttpManager getStringFromXML:launchResp tag:@"gamesession"];
|
NSString *gameSession = [HttpManager getStringFromXML:launchResp tag:@"gamesession"];
|
||||||
if (gameSession == NULL || [gameSession isEqualToString:@"0"]) {
|
if (launchResp == NULL) {
|
||||||
|
[_callbacks launchFailed:@"Failed to launch app"];
|
||||||
|
return FALSE;
|
||||||
|
} else if (gameSession == NULL || [gameSession isEqualToString:@"0"]) {
|
||||||
|
[_callbacks launchFailed:[HttpManager getStatusStringFromXML:launchResp]];
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,7 +102,11 @@
|
|||||||
[hMan newResumeRequestWithRiKey:[Utils bytesToHex:_config.riKey]
|
[hMan newResumeRequestWithRiKey:[Utils bytesToHex:_config.riKey]
|
||||||
riKeyId:_config.riKeyId]];
|
riKeyId:_config.riKeyId]];
|
||||||
NSString *resume = [HttpManager getStringFromXML:resumeResp tag:@"resume"];
|
NSString *resume = [HttpManager getStringFromXML:resumeResp tag:@"resume"];
|
||||||
if (resume == NULL || [resume isEqualToString:@"0"]) {
|
if (resumeResp == NULL) {
|
||||||
|
[_callbacks launchFailed:@"Failed to resume app"];
|
||||||
|
return FALSE;
|
||||||
|
} else if (resume == NULL || [resume isEqualToString:@"0"]) {
|
||||||
|
[_callbacks launchFailed:[HttpManager getStatusStringFromXML:resumeResp]];
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,10 +10,9 @@
|
|||||||
|
|
||||||
@implementation VideoDecoderRenderer {
|
@implementation VideoDecoderRenderer {
|
||||||
AVSampleBufferDisplayLayer* displayLayer;
|
AVSampleBufferDisplayLayer* displayLayer;
|
||||||
Boolean waitingForSps, waitingForPpsA, waitingForPpsB;
|
Boolean waitingForSps, waitingForPps;
|
||||||
|
|
||||||
NSData *spsData, *ppsDataA, *ppsDataB;
|
NSData *spsData, *ppsData;
|
||||||
unsigned char ppsDataAFirstByte;
|
|
||||||
CMVideoFormatDescriptionRef formatDesc;
|
CMVideoFormatDescriptionRef formatDesc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,8 +29,7 @@
|
|||||||
|
|
||||||
// We need some parameter sets before we can properly start decoding frames
|
// We need some parameter sets before we can properly start decoding frames
|
||||||
waitingForSps = true;
|
waitingForSps = true;
|
||||||
waitingForPpsA = true;
|
waitingForPps = true;
|
||||||
waitingForPpsB = true;
|
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
@@ -114,34 +112,27 @@
|
|||||||
unsigned char nalType = data[FRAME_START_PREFIX_SIZE] & 0x1F;
|
unsigned char nalType = data[FRAME_START_PREFIX_SIZE] & 0x1F;
|
||||||
OSStatus status;
|
OSStatus status;
|
||||||
|
|
||||||
if (formatDesc == NULL && (nalType == 0x7 || nalType == 0x8)) {
|
if (nalType == 0x7 || nalType == 0x8) {
|
||||||
if (waitingForSps && nalType == 0x7) {
|
if (nalType == 0x7) {
|
||||||
printf("Got SPS\n");
|
printf("Got SPS\n");
|
||||||
spsData = [NSData dataWithBytes:&data[FRAME_START_PREFIX_SIZE] length:length - FRAME_START_PREFIX_SIZE];
|
spsData = [NSData dataWithBytes:&data[FRAME_START_PREFIX_SIZE] length:length - FRAME_START_PREFIX_SIZE];
|
||||||
waitingForSps = false;
|
waitingForSps = false;
|
||||||
|
|
||||||
|
// We got a new SPS so wait for a new PPS to match it
|
||||||
|
waitingForPps = true;
|
||||||
}
|
}
|
||||||
// Nvidia's stream has 2 PPS NALUs so we'll wait for both of them
|
else if (nalType == 0x8) {
|
||||||
else if ((waitingForPpsA || waitingForPpsB) && nalType == 0x8) {
|
printf("Got PPS\n");
|
||||||
// Read the NALU's PPS index to figure out which PPS this is
|
ppsData = [NSData dataWithBytes:&data[FRAME_START_PREFIX_SIZE] length:length - FRAME_START_PREFIX_SIZE];
|
||||||
if (waitingForPpsA) {
|
waitingForPps = false;
|
||||||
printf("Got PPS 1\n");
|
|
||||||
ppsDataA = [NSData dataWithBytes:&data[FRAME_START_PREFIX_SIZE] length:length - FRAME_START_PREFIX_SIZE];
|
|
||||||
waitingForPpsA = false;
|
|
||||||
ppsDataAFirstByte = data[FRAME_START_PREFIX_SIZE + 1];
|
|
||||||
}
|
|
||||||
else if (data[FRAME_START_PREFIX_SIZE + 1] != ppsDataAFirstByte) {
|
|
||||||
printf("Got PPS 2\n");
|
|
||||||
ppsDataA = [NSData dataWithBytes:&data[FRAME_START_PREFIX_SIZE] length:length - FRAME_START_PREFIX_SIZE];
|
|
||||||
waitingForPpsB = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// See if we've got all the parameter sets we need
|
// See if we've got all the parameter sets we need
|
||||||
if (!waitingForSps && !waitingForPpsA && !waitingForPpsB) {
|
if (!waitingForSps && !waitingForPps) {
|
||||||
const uint8_t* const parameterSetPointers[] = { [spsData bytes], [ppsDataA bytes], [ppsDataB bytes] };
|
const uint8_t* const parameterSetPointers[] = { [spsData bytes], [ppsData bytes] };
|
||||||
const size_t parameterSetSizes[] = { [spsData length], [ppsDataA length], [ppsDataB length] };
|
const size_t parameterSetSizes[] = { [spsData length], [ppsData length] };
|
||||||
|
|
||||||
printf("Constructing format description\n");
|
printf("Constructing new format description\n");
|
||||||
status = CMVideoFormatDescriptionCreateFromH264ParameterSets(kCFAllocatorDefault,
|
status = CMVideoFormatDescriptionCreateFromH264ParameterSets(kCFAllocatorDefault,
|
||||||
2, /* count of parameter sets */
|
2, /* count of parameter sets */
|
||||||
parameterSetPointers,
|
parameterSetPointers,
|
||||||
|
|||||||
@@ -91,9 +91,9 @@
|
|||||||
[self presentViewController:alert animated:YES completion:nil];
|
[self presentViewController:alert animated:YES completion:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) launchFailed {
|
- (void) launchFailed:(NSString*)message {
|
||||||
UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"Connection Failed"
|
UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"Connection Failed"
|
||||||
message:@"Failed to start app"
|
message:message
|
||||||
preferredStyle:UIAlertControllerStyleAlert];
|
preferredStyle:UIAlertControllerStyleAlert];
|
||||||
[alert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDestructive handler:^(UIAlertAction* action){
|
[alert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDestructive handler:^(UIAlertAction* action){
|
||||||
[self performSegueWithIdentifier:@"returnToMainFrame" sender:self];
|
[self performSegueWithIdentifier:@"returnToMainFrame" sender:self];
|
||||||
|
|||||||
+1
-1
Submodule limelight-common-c updated: 71ace097f8...91f0351671.
Reference in new issue
Block a user