mirror of
https://github.com/moonlight-stream/moonlight-ios.git
synced 2025-07-01 23:35:59 +00:00
Created new host discovery system
- now store host uuid and mac address - use uuid to check for duplicate hosts - try local and external IPs - pair status is shown - server status is shown - validate host when manually adding
This commit is contained in:
parent
0e2765ad86
commit
e8c8f4f8e9
@ -28,6 +28,7 @@
|
||||
FB290E7919B37D81004C83CF /* iPad.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FB290E7819B37D81004C83CF /* iPad.storyboard */; };
|
||||
FB290E7B19B38036004C83CF /* iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FB290E7A19B38036004C83CF /* iPhone.storyboard */; };
|
||||
FB4678ED1A50C40900377732 /* OnScreenControls.m in Sources */ = {isa = PBXBuildFile; fileRef = FB4678EC1A50C40900377732 /* OnScreenControls.m */; };
|
||||
FB4678FA1A55FFAD00377732 /* DiscoveryManager.m in Sources */ = {isa = PBXBuildFile; fileRef = FB4678F91A55FFAD00377732 /* DiscoveryManager.m */; };
|
||||
FB7E794419C8B71B00A15F68 /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FB7E794319C8B71B00A15F68 /* libiconv.dylib */; };
|
||||
FB89462819F646E200339C8A /* CryptoManager.m in Sources */ = {isa = PBXBuildFile; fileRef = FB89460619F646E200339C8A /* CryptoManager.m */; };
|
||||
FB89462919F646E200339C8A /* mkcert.c in Sources */ = {isa = PBXBuildFile; fileRef = FB89460719F646E200339C8A /* mkcert.c */; };
|
||||
@ -40,7 +41,6 @@
|
||||
FB89463019F646E200339C8A /* StreamConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = FB89461919F646E200339C8A /* StreamConfiguration.m */; };
|
||||
FB89463119F646E200339C8A /* StreamManager.m in Sources */ = {isa = PBXBuildFile; fileRef = FB89461B19F646E200339C8A /* StreamManager.m */; };
|
||||
FB89463219F646E200339C8A /* VideoDecoderRenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = FB89461D19F646E200339C8A /* VideoDecoderRenderer.m */; };
|
||||
FB89463319F646E200339C8A /* Computer.m in Sources */ = {isa = PBXBuildFile; fileRef = FB89462019F646E200339C8A /* Computer.m */; };
|
||||
FB89463419F646E200339C8A /* Utils.m in Sources */ = {isa = PBXBuildFile; fileRef = FB89462219F646E200339C8A /* Utils.m */; };
|
||||
FB89463519F646E200339C8A /* MainFrameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FB89462519F646E200339C8A /* MainFrameViewController.m */; };
|
||||
FB89463619F646E200339C8A /* StreamFrameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FB89462719F646E200339C8A /* StreamFrameViewController.m */; };
|
||||
@ -110,6 +110,8 @@
|
||||
FB4678EB1A50C40900377732 /* OnScreenControls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OnScreenControls.h; sourceTree = "<group>"; };
|
||||
FB4678EC1A50C40900377732 /* OnScreenControls.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OnScreenControls.m; sourceTree = "<group>"; };
|
||||
FB4678F21A51BDCB00377732 /* Limelight 0.3.0.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Limelight 0.3.0.xcdatamodel"; sourceTree = "<group>"; };
|
||||
FB4678F81A55FFAD00377732 /* DiscoveryManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiscoveryManager.h; sourceTree = "<group>"; };
|
||||
FB4678F91A55FFAD00377732 /* DiscoveryManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DiscoveryManager.m; sourceTree = "<group>"; };
|
||||
FB7E794319C8B71B00A15F68 /* libiconv.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libiconv.dylib; path = usr/lib/libiconv.dylib; sourceTree = SDKROOT; };
|
||||
FB89460519F646E200339C8A /* CryptoManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoManager.h; sourceTree = "<group>"; };
|
||||
FB89460619F646E200339C8A /* CryptoManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CryptoManager.m; sourceTree = "<group>"; };
|
||||
@ -133,8 +135,6 @@
|
||||
FB89461B19F646E200339C8A /* StreamManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StreamManager.m; sourceTree = "<group>"; };
|
||||
FB89461C19F646E200339C8A /* VideoDecoderRenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoDecoderRenderer.h; sourceTree = "<group>"; };
|
||||
FB89461D19F646E200339C8A /* VideoDecoderRenderer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VideoDecoderRenderer.m; sourceTree = "<group>"; };
|
||||
FB89461F19F646E200339C8A /* Computer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Computer.h; sourceTree = "<group>"; };
|
||||
FB89462019F646E200339C8A /* Computer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Computer.m; sourceTree = "<group>"; };
|
||||
FB89462119F646E200339C8A /* Utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Utils.h; sourceTree = "<group>"; };
|
||||
FB89462219F646E200339C8A /* Utils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Utils.m; sourceTree = "<group>"; };
|
||||
FB89462419F646E200339C8A /* MainFrameViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainFrameViewController.h; sourceTree = "<group>"; };
|
||||
@ -413,6 +413,8 @@
|
||||
FB89461419F646E200339C8A /* PairManager.m */,
|
||||
FBD3494119FC9C04002D2A60 /* AppManager.h */,
|
||||
FBD3494219FC9C04002D2A60 /* AppManager.m */,
|
||||
FB4678F81A55FFAD00377732 /* DiscoveryManager.h */,
|
||||
FB4678F91A55FFAD00377732 /* DiscoveryManager.m */,
|
||||
);
|
||||
path = Network;
|
||||
sourceTree = "<group>";
|
||||
@ -435,8 +437,6 @@
|
||||
FB89461E19F646E200339C8A /* Utility */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FB89461F19F646E200339C8A /* Computer.h */,
|
||||
FB89462019F646E200339C8A /* Computer.m */,
|
||||
FBDE86E719F82315001C18A8 /* App.h */,
|
||||
FBDE86E819F82315001C18A8 /* App.m */,
|
||||
FB89462119F646E200339C8A /* Utils.h */,
|
||||
@ -758,7 +758,6 @@
|
||||
FB290D0419B2C406004C83CF /* AppDelegate.m in Sources */,
|
||||
FB89463419F646E200339C8A /* Utils.m in Sources */,
|
||||
FBDE86E619F82297001C18A8 /* UIAppView.m in Sources */,
|
||||
FB89463319F646E200339C8A /* Computer.m in Sources */,
|
||||
FB89462F19F646E200339C8A /* Connection.m in Sources */,
|
||||
FB89462919F646E200339C8A /* mkcert.c in Sources */,
|
||||
FBDE86E019F7A837001C18A8 /* UIComputerView.m in Sources */,
|
||||
@ -769,6 +768,7 @@
|
||||
FB89462C19F646E200339C8A /* HttpManager.m in Sources */,
|
||||
FB89462D19F646E200339C8A /* MDNSManager.m in Sources */,
|
||||
FB89462B19F646E200339C8A /* StreamView.m in Sources */,
|
||||
FB4678FA1A55FFAD00377732 /* DiscoveryManager.m in Sources */,
|
||||
FBD3495B1A004411002D2A60 /* Host.m in Sources */,
|
||||
FB89463519F646E200339C8A /* MainFrameViewController.m in Sources */,
|
||||
FB89463619F646E200339C8A /* StreamFrameViewController.m in Sources */,
|
||||
|
@ -19,6 +19,6 @@
|
||||
- (Settings*) retrieveSettings;
|
||||
- (NSArray*) retrieveHosts;
|
||||
- (void) saveHosts;
|
||||
- (Host*) createHost:(NSString*)name hostname:(NSString*)address;
|
||||
- (Host*) createHost;
|
||||
|
||||
@end
|
||||
|
@ -45,12 +45,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (Host*) createHost:(NSString*)name hostname:(NSString*)address {
|
||||
- (Host*) createHost {
|
||||
NSEntityDescription* entity = [NSEntityDescription entityForName:@"Host" inManagedObjectContext:[self.appDelegate managedObjectContext]];
|
||||
Host* host = [[Host alloc] initWithEntity:entity insertIntoManagedObjectContext:[self.appDelegate managedObjectContext]];
|
||||
|
||||
host.name = name;
|
||||
host.address = address;
|
||||
return host;
|
||||
}
|
||||
|
||||
|
@ -8,11 +8,17 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <CoreData/CoreData.h>
|
||||
|
||||
#import "Utils.h"
|
||||
|
||||
@interface Host : NSManagedObject
|
||||
|
||||
@property (nonatomic, retain) NSString * address;
|
||||
@property (nonatomic, retain) NSString * name;
|
||||
@property (nonatomic, retain) NSString * address;
|
||||
@property (nonatomic, retain) NSString * localAddress;
|
||||
@property (nonatomic, retain) NSString * externalAddress;
|
||||
@property (nonatomic, retain) NSString * uuid;
|
||||
@property (nonatomic, retain) NSString * mac;
|
||||
@property (nonatomic) BOOL online;
|
||||
@property (nonatomic) PairState pairState;
|
||||
|
||||
@end
|
||||
|
@ -11,7 +11,13 @@
|
||||
|
||||
@implementation Host
|
||||
|
||||
@dynamic address;
|
||||
@dynamic name;
|
||||
@dynamic address;
|
||||
@dynamic localAddress;
|
||||
@dynamic externalAddress;
|
||||
@dynamic uuid;
|
||||
@dynamic mac;
|
||||
@dynamic pairState;
|
||||
@synthesize online;
|
||||
|
||||
@end
|
||||
|
@ -2,7 +2,12 @@
|
||||
<model userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="6254" systemVersion="14C81f" minimumToolsVersion="Automatic" macOSVersion="Automatic" iOSVersion="Automatic">
|
||||
<entity name="Host" representedClassName="Host" syncable="YES">
|
||||
<attribute name="address" attributeType="String" syncable="YES"/>
|
||||
<attribute name="externalAddress" optional="YES" attributeType="String" syncable="YES"/>
|
||||
<attribute name="localAddress" optional="YES" attributeType="String" syncable="YES"/>
|
||||
<attribute name="mac" optional="YES" attributeType="String" syncable="YES"/>
|
||||
<attribute name="name" attributeType="String" syncable="YES"/>
|
||||
<attribute name="pairState" optional="YES" attributeType="Integer 32" defaultValueString="0" syncable="YES"/>
|
||||
<attribute name="uuid" optional="YES" attributeType="String" syncable="YES"/>
|
||||
</entity>
|
||||
<entity name="Settings" representedClassName="Settings" syncable="YES">
|
||||
<attribute name="bitrate" attributeType="Integer 32" defaultValueString="10000" syncable="YES"/>
|
||||
@ -12,7 +17,7 @@
|
||||
<attribute name="width" attributeType="Integer 32" defaultValueString="1280" syncable="YES"/>
|
||||
</entity>
|
||||
<elements>
|
||||
<element name="Host" positionX="0" positionY="0" width="128" height="73"/>
|
||||
<element name="Host" positionX="0" positionY="0" width="128" height="148"/>
|
||||
<element name="Settings" positionX="0" positionY="0" width="128" height="118"/>
|
||||
</elements>
|
||||
</model>
|
27
Limelight/Network/DiscoveryManager.h
Normal file
27
Limelight/Network/DiscoveryManager.h
Normal file
@ -0,0 +1,27 @@
|
||||
//
|
||||
// DiscoveryManager.h
|
||||
// Limelight
|
||||
//
|
||||
// Created by Diego Waxemberg on 1/1/15.
|
||||
// Copyright (c) 2015 Limelight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "MDNSManager.h"
|
||||
#import "Host.h"
|
||||
|
||||
@protocol DiscoveryCallback <NSObject>
|
||||
|
||||
- (void) updateAllHosts:(NSArray*)hosts;
|
||||
|
||||
@end
|
||||
|
||||
@interface DiscoveryManager : NSOperation <MDNSCallback>
|
||||
|
||||
- (id) initWithHosts:(NSArray*)hosts andCallback:(id<DiscoveryCallback>) callback;
|
||||
- (void) startDiscovery;
|
||||
- (void) stopDiscovery;
|
||||
- (void) addHostToDiscovery:(Host*)host;
|
||||
- (void) discoverHost:(NSString*)hostAddress withCallback:(void (^)(Host*))callback;
|
||||
|
||||
@end
|
149
Limelight/Network/DiscoveryManager.m
Normal file
149
Limelight/Network/DiscoveryManager.m
Normal file
@ -0,0 +1,149 @@
|
||||
//
|
||||
// DiscoveryManager.m
|
||||
// Limelight
|
||||
//
|
||||
// Created by Diego Waxemberg on 1/1/15.
|
||||
// Copyright (c) 2015 Limelight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "DiscoveryManager.h"
|
||||
#import "CryptoManager.h"
|
||||
#import "HttpManager.h"
|
||||
#import "Utils.h"
|
||||
#import "DataManager.h"
|
||||
|
||||
@implementation DiscoveryManager {
|
||||
NSMutableArray* _hostQueue;
|
||||
NSMutableArray* _discoveredHosts;
|
||||
id<DiscoveryCallback> _callback;
|
||||
MDNSManager* _mdnsMan;
|
||||
NSOperationQueue* _opQueue;
|
||||
NSString* _uniqueId;
|
||||
NSData* _cert;
|
||||
BOOL shouldDiscover;
|
||||
}
|
||||
|
||||
- (id)initWithHosts:(NSArray *)hosts andCallback:(id<DiscoveryCallback>)callback {
|
||||
self = [super init];
|
||||
_hostQueue = [NSMutableArray arrayWithArray:hosts];
|
||||
_callback = callback;
|
||||
_discoveredHosts = [[NSMutableArray alloc] init];
|
||||
_opQueue = [[NSOperationQueue alloc] init];
|
||||
_mdnsMan = [[MDNSManager alloc] initWithCallback:self];
|
||||
[CryptoManager generateKeyPairUsingSSl];
|
||||
_uniqueId = [CryptoManager getUniqueID];
|
||||
_cert = [CryptoManager readCertFromFile];
|
||||
shouldDiscover = NO;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (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]];
|
||||
|
||||
Host* host = nil;
|
||||
if ([[HttpManager getStatusStringFromXML:serverInfoData] isEqualToString:@"OK"]) {
|
||||
host = [[[DataManager alloc] init] createHost];
|
||||
host.address = hostAddress;
|
||||
[self updateHost:host withServerInfo:serverInfoData];
|
||||
[self addHostToDiscovery:host];
|
||||
}
|
||||
callback(host);
|
||||
}
|
||||
|
||||
- (void) discoverHost:(Host*)host {
|
||||
if (!shouldDiscover) return;
|
||||
BOOL receivedResponse = NO;
|
||||
if (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"]) {
|
||||
[self updateHost:host withServerInfo:serverInfoData];
|
||||
host.address = host.localAddress;
|
||||
receivedResponse = YES;
|
||||
}
|
||||
}
|
||||
if (shouldDiscover && !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"]) {
|
||||
[self updateHost:host withServerInfo:serverInfoData];
|
||||
host.address = host.externalAddress;
|
||||
receivedResponse = YES;
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldDiscover && !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"]) {
|
||||
[self updateHost:host withServerInfo:serverInfoData];
|
||||
receivedResponse = YES;
|
||||
}
|
||||
}
|
||||
host.online = receivedResponse;
|
||||
if (receivedResponse) {
|
||||
NSLog(@"Received response from: %@\n{\n\t address:%@ \n\t localAddress:%@ \n\t externalAddress:%@ \n\t uuid:%@ \n\t mac:%@ \n\t pairState:%d \n\t online:%d \n}", host.name, host.address, host.localAddress, host.externalAddress, host.uuid, host.mac, host.pairState, host.online);
|
||||
}
|
||||
// If the host has already been discovered, we update the reference
|
||||
BOOL hostInList = NO;
|
||||
for (int i = 0; i < _discoveredHosts.count; i++) {
|
||||
Host* discoveredHost = [_discoveredHosts objectAtIndex:i];
|
||||
if ([discoveredHost.uuid isEqualToString:host.uuid]) {
|
||||
[_discoveredHosts removeObject:discoveredHost];
|
||||
[_discoveredHosts insertObject:host atIndex:i];
|
||||
hostInList = YES;
|
||||
}
|
||||
}
|
||||
if (!hostInList) {
|
||||
[_discoveredHosts addObject:host];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) updateHost:(Host*)host withServerInfo:(NSData*)serverInfoData {
|
||||
host.name = [HttpManager getStringFromXML:serverInfoData tag:@"hostname"];
|
||||
host.externalAddress = [HttpManager getStringFromXML:serverInfoData tag:@"ExternalIP"];
|
||||
host.localAddress = [HttpManager getStringFromXML:serverInfoData tag:@"LocalIP"];
|
||||
host.uuid = [HttpManager getStringFromXML:serverInfoData tag:@"uniqueid"];
|
||||
host.mac = [HttpManager getStringFromXML:serverInfoData tag:@"mac"];
|
||||
NSString* pairState = [HttpManager getStringFromXML:serverInfoData tag:@"PairStatus"];
|
||||
if ([pairState isEqualToString:@"1"]) {
|
||||
host.pairState = PairStatePaired;
|
||||
} else {
|
||||
host.pairState = PairStateUnpaired;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) startDiscovery {
|
||||
NSLog(@"Starting discovery");
|
||||
shouldDiscover = YES;
|
||||
[_mdnsMan searchForHosts];
|
||||
[_opQueue addOperation:self];
|
||||
}
|
||||
|
||||
- (void) stopDiscovery {
|
||||
shouldDiscover = NO;
|
||||
[_mdnsMan stopSearching];
|
||||
}
|
||||
|
||||
- (void) addHostToDiscovery:(Host *)host {
|
||||
[_hostQueue addObject:host];
|
||||
}
|
||||
|
||||
- (void)updateHosts:(NSArray *)hosts {
|
||||
[_hostQueue addObjectsFromArray:hosts];
|
||||
}
|
||||
|
||||
- (void)main {
|
||||
while (shouldDiscover && !self.isCancelled) {
|
||||
NSLog(@"Running discovery loop");
|
||||
[_discoveredHosts removeAllObjects];
|
||||
for (Host* host in _hostQueue) {
|
||||
[self discoverHost:host];
|
||||
}
|
||||
[_callback updateAllHosts:_discoveredHosts];
|
||||
[NSThread sleepForTimeInterval:3.0f];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
@ -7,7 +7,8 @@
|
||||
//
|
||||
|
||||
#import "MDNSManager.h"
|
||||
#import "Computer.h"
|
||||
#import "Host.h"
|
||||
#import "DataManager.h"
|
||||
|
||||
@implementation MDNSManager {
|
||||
NSNetServiceBrowser* mDNSBrowser;
|
||||
@ -46,9 +47,12 @@ static NSString* NV_SERVICE_TYPE = @"_nvstream._tcp";
|
||||
|
||||
- (NSArray*) getFoundHosts {
|
||||
NSMutableArray* hosts = [[NSMutableArray alloc] init];
|
||||
DataManager* dataMan = [[DataManager alloc] init];
|
||||
for (NSNetService* service in services) {
|
||||
if (service.hostName != nil) {
|
||||
[hosts addObject:[[Computer alloc] initWithHost:service]];
|
||||
Host* host = [dataMan createHost];
|
||||
host.address = service.hostName;
|
||||
[hosts addObject:host];
|
||||
}
|
||||
}
|
||||
return hosts;
|
||||
|
@ -7,18 +7,18 @@
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "Computer.h"
|
||||
#import "Host.h"
|
||||
|
||||
@protocol HostCallback <NSObject>
|
||||
|
||||
- (void) hostClicked:(Computer*)computer;
|
||||
- (void) hostClicked:(Host*)host;
|
||||
- (void) addHostClicked;
|
||||
|
||||
@end
|
||||
|
||||
@interface UIComputerView : UIView
|
||||
|
||||
- (id) initWithComputer:(Computer*)computer andCallback:(id<HostCallback>)callback;
|
||||
- (id) initWithComputer:(Host*)host andCallback:(id<HostCallback>)callback;
|
||||
- (id) initForAddWithCallback:(id<HostCallback>)callback;
|
||||
|
||||
- (NSString*) online;
|
||||
@end
|
||||
|
@ -9,9 +9,11 @@
|
||||
#import "UIComputerView.h"
|
||||
|
||||
@implementation UIComputerView {
|
||||
Computer* _computer;
|
||||
Host* _host;
|
||||
UIButton* _hostButton;
|
||||
UILabel* _hostLabel;
|
||||
UILabel* _hostStatus;
|
||||
UILabel* _hostPairState;
|
||||
id<HostCallback> _callback;
|
||||
CGSize _labelSize;
|
||||
}
|
||||
@ -29,27 +31,61 @@ static int LABEL_DY = 20;
|
||||
_hostButton.layer.shadowOpacity = 0.7;
|
||||
|
||||
_hostLabel = [[UILabel alloc] init];
|
||||
|
||||
_hostStatus = [[UILabel alloc] init];
|
||||
_hostPairState = [[UILabel alloc] init];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) initWithComputer:(Computer*)computer andCallback:(id<HostCallback>)callback {
|
||||
- (id) initWithComputer:(Host*)host andCallback:(id<HostCallback>)callback {
|
||||
self = [self init];
|
||||
_computer = computer;
|
||||
_host = host;
|
||||
_callback = callback;
|
||||
|
||||
[_hostLabel setText:[_computer displayName]];
|
||||
[_hostLabel setText:_host.name];
|
||||
[_hostLabel sizeToFit];
|
||||
_hostLabel.textColor = [UIColor whiteColor];
|
||||
|
||||
|
||||
switch (host.pairState) {
|
||||
case PairStateUnknown:
|
||||
[_hostPairState setText:@"Pair State Unknown"];
|
||||
break;
|
||||
case PairStateUnpaired:
|
||||
[_hostPairState setText:@"Not Paired"];
|
||||
break;
|
||||
case PairStatePaired:
|
||||
[_hostPairState setText:@"Paired"];
|
||||
break;
|
||||
}
|
||||
[_hostPairState sizeToFit];
|
||||
_hostPairState.textColor = [UIColor whiteColor];
|
||||
|
||||
if (host.online) {
|
||||
_hostStatus.text = @"Online";
|
||||
_hostStatus.textColor = [UIColor greenColor];
|
||||
} else {
|
||||
_hostStatus.text = @"Offline";
|
||||
_hostStatus.textColor = [UIColor grayColor];
|
||||
}
|
||||
[_hostStatus sizeToFit];
|
||||
|
||||
[_hostButton addTarget:self action:@selector(hostClicked) forControlEvents:UIControlEventTouchUpInside];
|
||||
_hostLabel.center = CGPointMake(_hostButton.frame.origin.x + (_hostButton.frame.size.width / 2), _hostButton.frame.origin.y + _hostButton.frame.size.height + LABEL_DY);
|
||||
_hostPairState.center = CGPointMake(_hostLabel.center.x, _hostLabel.center.y + LABEL_DY);
|
||||
_hostStatus.center = CGPointMake(_hostPairState.center.x, _hostPairState.center.y + LABEL_DY);
|
||||
|
||||
[self updateBounds];
|
||||
[self addSubview:_hostButton];
|
||||
[self addSubview:_hostLabel];
|
||||
|
||||
[self addSubview:_hostStatus];
|
||||
[self addSubview:_hostPairState];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSString *)online {
|
||||
return _hostStatus.text;
|
||||
}
|
||||
|
||||
- (void) updateBounds {
|
||||
float x = _hostButton.frame.origin.x < _hostLabel.frame.origin.x ? _hostButton.frame.origin.x : _hostLabel.frame.origin.x;
|
||||
float y = _hostButton.frame.origin.y < _hostLabel.frame.origin.y ? _hostButton.frame.origin.y : _hostLabel.frame.origin.y;
|
||||
@ -83,19 +119,11 @@ static int LABEL_DY = 20;
|
||||
}
|
||||
|
||||
- (void) hostClicked {
|
||||
[_callback hostClicked:_computer];
|
||||
[_callback hostClicked:_host];
|
||||
}
|
||||
|
||||
- (void) addClicked {
|
||||
[_callback addHostClicked];
|
||||
}
|
||||
|
||||
/*
|
||||
// Only override drawRect: if you perform custom drawing.
|
||||
// An empty implementation adversely affects performance during animation.
|
||||
- (void)drawRect:(CGRect)rect {
|
||||
// Drawing code
|
||||
}
|
||||
*/
|
||||
|
||||
@end
|
||||
|
@ -1,19 +0,0 @@
|
||||
//
|
||||
// Computer.h
|
||||
// Limelight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/14/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface Computer : NSObject
|
||||
@property NSString* displayName;
|
||||
@property NSString* hostName;
|
||||
@property BOOL paired;
|
||||
|
||||
- (id) initWithHost:(NSNetService*)host;
|
||||
- (id) initWithIp:(NSString*)host;
|
||||
|
||||
@end
|
@ -1,47 +0,0 @@
|
||||
//
|
||||
// Computer.m
|
||||
// Limelight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/14/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Computer.h"
|
||||
|
||||
@implementation Computer
|
||||
|
||||
- (id) initWithHost:(NSNetService *)host {
|
||||
self = [super init];
|
||||
|
||||
self.hostName = [host hostName];
|
||||
self.displayName = [host name];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) initWithIp:(NSString*)host {
|
||||
self = [super init];
|
||||
|
||||
self.hostName = host;
|
||||
self.displayName = host;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object {
|
||||
if ([object isKindOfClass:[Computer class]]) {
|
||||
return [self.hostName isEqual:[object valueForKey:@"hostName"]];
|
||||
} else {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSUInteger)hash {
|
||||
NSUInteger prime = 31;
|
||||
NSUInteger result = 1;
|
||||
result = prime * result + (self.hostName == nil ? 0 : [self.hostName hash]);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
@ -10,6 +10,14 @@
|
||||
|
||||
@interface Utils : NSObject
|
||||
|
||||
typedef NS_ENUM(int, PairState) {
|
||||
PairStateUnknown,
|
||||
PairStateUnpaired,
|
||||
PairStatePaired
|
||||
};
|
||||
|
||||
FOUNDATION_EXPORT NSString *const deviceName;
|
||||
|
||||
+ (NSData*) randomBytes:(NSInteger)length;
|
||||
+ (NSString*) bytesToHex:(NSData*)data;
|
||||
+ (NSData*) hexToBytes:(NSString*) hex;
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <netdb.h>
|
||||
|
||||
@implementation Utils
|
||||
NSString *const deviceName = @"roth";
|
||||
|
||||
+ (NSData*) randomBytes:(NSInteger)length {
|
||||
char* bytes = malloc(length);
|
||||
|
@ -7,7 +7,7 @@
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "MDNSManager.h"
|
||||
#import "DiscoveryManager.h"
|
||||
#import "PairManager.h"
|
||||
#import "StreamConfiguration.h"
|
||||
#import "UIComputerView.h"
|
||||
@ -15,7 +15,7 @@
|
||||
#import "AppManager.h"
|
||||
#import "SWRevealViewController.h"
|
||||
|
||||
@interface MainFrameViewController : UICollectionViewController <MDNSCallback, PairCallback, HostCallback, AppCallback, AppAssetCallback, NSURLConnectionDelegate, SWRevealViewControllerDelegate>
|
||||
@interface MainFrameViewController : UICollectionViewController <DiscoveryCallback, PairCallback, HostCallback, AppCallback, AppAssetCallback, NSURLConnectionDelegate, SWRevealViewControllerDelegate>
|
||||
@property (strong, nonatomic) IBOutlet UIButton *limelightLogoButton;
|
||||
@property (weak, nonatomic) IBOutlet UIBarButtonItem *computerNameButton;
|
||||
|
||||
|
@ -6,7 +6,6 @@
|
||||
//
|
||||
|
||||
#import "MainFrameViewController.h"
|
||||
#import "Computer.h"
|
||||
#import "CryptoManager.h"
|
||||
#import "HttpManager.h"
|
||||
#import "Connection.h"
|
||||
@ -22,17 +21,15 @@
|
||||
|
||||
@implementation MainFrameViewController {
|
||||
NSOperationQueue* _opQueue;
|
||||
MDNSManager* _mDNSManager;
|
||||
Computer* _selectedHost;
|
||||
Host* _selectedHost;
|
||||
NSString* _uniqueId;
|
||||
NSData* _cert;
|
||||
NSString* _currentGame;
|
||||
|
||||
DiscoveryManager* _discMan;
|
||||
UIAlertView* _pairAlert;
|
||||
UIScrollView* hostScrollView;
|
||||
int currentPosition;
|
||||
}
|
||||
static NSString* deviceName = @"roth";
|
||||
static NSMutableSet* hostList;
|
||||
static NSArray* appList;
|
||||
static StreamConfiguration* streamConfig;
|
||||
@ -66,13 +63,14 @@ static StreamConfiguration* streamConfig;
|
||||
|
||||
- (void)alreadyPaired {
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:_selectedHost.hostName uniqueId:_uniqueId deviceName:deviceName cert:_cert];
|
||||
NSData* appListResp = [hMan executeRequestSynchronously:[hMan newAppListRequest]];
|
||||
appList = [HttpManager getAppListFromXML:appListResp];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self updateApps];
|
||||
_computerNameButton.title = _selectedHost.displayName;
|
||||
NSLog(@"Setting _computerNameButton.title: %@", _selectedHost.name);
|
||||
_computerNameButton.title = _selectedHost.name;
|
||||
});
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:_selectedHost.address uniqueId:_uniqueId deviceName:deviceName cert:_cert];
|
||||
NSData* appListResp = [hMan executeRequestSynchronously:[hMan newAppListRequest]];
|
||||
appList = [HttpManager getAppListFromXML:appListResp];
|
||||
|
||||
[AppManager retrieveAppAssets:appList withManager:hMan andCallback:self];
|
||||
});
|
||||
@ -97,11 +95,11 @@ static StreamConfiguration* streamConfig;
|
||||
[self presentViewController:alert animated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (void) hostClicked:(Computer *)computer {
|
||||
NSLog(@"Clicked host: %@", computer.displayName);
|
||||
_selectedHost = computer;
|
||||
- (void) hostClicked:(Host *)host {
|
||||
NSLog(@"Clicked host: %@", host.name);
|
||||
_selectedHost = host;
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:computer.hostName uniqueId:_uniqueId deviceName:deviceName cert:_cert];
|
||||
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");
|
||||
@ -119,17 +117,24 @@ static StreamConfiguration* streamConfig;
|
||||
UIAlertController* alertController = [UIAlertController alertControllerWithTitle:@"Host Address" message:@"Please enter a hostname or IP address" preferredStyle:UIAlertControllerStyleAlert];
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]];
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){
|
||||
NSString* host = ((UITextField*)[[alertController textFields] objectAtIndex:0]).text;
|
||||
Computer* newHost = [[Computer alloc] initWithIp:host];
|
||||
[hostList addObject:newHost];
|
||||
[self updateHosts:[hostList allObjects]];
|
||||
DataManager* dataMan = [[DataManager alloc] init];
|
||||
[dataMan createHost:newHost.displayName hostname:newHost.hostName];
|
||||
[dataMan saveHosts];
|
||||
|
||||
//TODO: get pair state
|
||||
|
||||
|
||||
NSString* hostAddress = ((UITextField*)[[alertController textFields] objectAtIndex:0]).text;
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
|
||||
[_discMan discoverHost:hostAddress withCallback:^(Host* host){
|
||||
if (host != nil) {
|
||||
DataManager* dataMan = [[DataManager alloc] init];
|
||||
[dataMan saveHosts];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[hostList addObject:host];
|
||||
[self updateHosts];
|
||||
});
|
||||
} else {
|
||||
UIAlertController* hostNotFoundAlert = [UIAlertController alertControllerWithTitle:@"Host Not Found" message:[NSString stringWithFormat:@"Unable to connect to host: \n%@", hostAddress] preferredStyle:UIAlertControllerStyleAlert];
|
||||
[hostNotFoundAlert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDestructive handler:nil]];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self presentViewController:hostNotFoundAlert animated:YES completion:nil];
|
||||
});
|
||||
}
|
||||
}];});
|
||||
}]];
|
||||
[alertController addTextFieldWithConfigurationHandler:nil];
|
||||
[self presentViewController:alertController animated:YES completion:nil];
|
||||
@ -138,8 +143,8 @@ static StreamConfiguration* streamConfig;
|
||||
- (void) appClicked:(App *)app {
|
||||
NSLog(@"Clicked app: %@", app.appName);
|
||||
streamConfig = [[StreamConfiguration alloc] init];
|
||||
streamConfig.host = _selectedHost.hostName;
|
||||
streamConfig.hostAddr = [Utils resolveHost:_selectedHost.hostName];
|
||||
streamConfig.host = _selectedHost.address;
|
||||
streamConfig.hostAddr = [Utils resolveHost:_selectedHost.address];
|
||||
streamConfig.appID = app.appId;
|
||||
if (streamConfig.hostAddr == 0) {
|
||||
[self displayDnsFailedDialog];
|
||||
@ -169,7 +174,7 @@ static StreamConfiguration* streamConfig;
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:@"Quit App" 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.hostName uniqueId:_uniqueId deviceName:deviceName cert:_cert];
|
||||
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;
|
||||
@ -198,15 +203,6 @@ static StreamConfiguration* streamConfig;
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (App*) findAppInAppList:(NSString*)appId {
|
||||
for (App* app in appList) {
|
||||
if ([app.appId isEqualToString:appId]) {
|
||||
return app;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)revealController:(SWRevealViewController *)revealController didMoveToPosition:(FrontViewPosition)position {
|
||||
// If we moved back to the center position, we should save the settings
|
||||
if (position == FrontViewPositionLeft) {
|
||||
@ -253,7 +249,9 @@ static StreamConfiguration* streamConfig;
|
||||
[hostScrollView setShowsHorizontalScrollIndicator:NO];
|
||||
|
||||
[self retrieveSavedHosts];
|
||||
[self updateHosts:[hostList allObjects]];
|
||||
_discMan = [[DiscoveryManager alloc] initWithHosts:[hostList allObjects] andCallback:self];
|
||||
|
||||
[self updateHosts];
|
||||
[self.view addSubview:hostScrollView];
|
||||
}
|
||||
|
||||
@ -267,8 +265,7 @@ static StreamConfiguration* streamConfig;
|
||||
[self.navigationController.navigationBar setShadowImage:fakeImage];
|
||||
[self.navigationController.navigationBar setBackgroundImage:fakeImage forBarPosition:UIBarPositionAny barMetrics:UIBarMetricsDefault];
|
||||
|
||||
_mDNSManager = [[MDNSManager alloc] initWithCallback:self];
|
||||
[_mDNSManager searchForHosts];
|
||||
[_discMan startDiscovery];
|
||||
|
||||
// This will refresh the applist
|
||||
if (_selectedHost != nil) {
|
||||
@ -279,28 +276,38 @@ static StreamConfiguration* streamConfig;
|
||||
- (void)viewDidDisappear:(BOOL)animated
|
||||
{
|
||||
[super viewDidDisappear:animated];
|
||||
[_mDNSManager stopSearching];
|
||||
// when discovery stops, we must create a new instance because you cannot restart an NSOperation when it is finished
|
||||
[_discMan stopDiscovery];
|
||||
_discMan = [[DiscoveryManager alloc] initWithHosts:[hostList allObjects] andCallback:self];
|
||||
// In case the host objects were updated in the background
|
||||
[[[DataManager alloc] init] saveHosts];
|
||||
}
|
||||
|
||||
- (void) retrieveSavedHosts {
|
||||
//TODO: Get rid of Computer and only use Host
|
||||
|
||||
DataManager* dataMan = [[DataManager alloc] init];
|
||||
NSArray* hosts = [dataMan retrieveHosts];
|
||||
for (Host* host in hosts) {
|
||||
Computer* comp = [[Computer alloc] initWithIp:host.address];
|
||||
comp.displayName = host.name;
|
||||
[hostList addObject:comp];
|
||||
}
|
||||
[hostList addObjectsFromArray:hosts];
|
||||
}
|
||||
|
||||
- (void)updateHosts:(NSArray *)hosts {
|
||||
[hostList addObjectsFromArray:hosts];
|
||||
- (void) updateAllHosts:(NSArray *)hosts {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
NSLog(@"New host list:");
|
||||
for (Host* host in hosts) {
|
||||
NSLog(@"Host: \n{\n\t name:%@ \n\t address:%@ \n\t localAddress:%@ \n\t externalAddress:%@ \n\t uuid:%@ \n\t mac:%@ \n\t pairState:%d \n\t online:%d \n}", host.name, host.address, host.localAddress, host.externalAddress, host.uuid, host.mac, host.pairState, host.online);
|
||||
}
|
||||
[hostList removeAllObjects];
|
||||
[hostList addObjectsFromArray:hosts];
|
||||
[self updateHosts];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)updateHosts {
|
||||
NSLog(@"Updating hosts...");
|
||||
[[hostScrollView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
|
||||
UIComputerView* addComp = [[UIComputerView alloc] initForAddWithCallback:self];
|
||||
UIComputerView* compView;
|
||||
float prevEdge = -1;
|
||||
for (Computer* comp in hostList) {
|
||||
for (Host* comp in hostList) {
|
||||
compView = [[UIComputerView alloc] initWithComputer:comp andCallback:self];
|
||||
compView.center = CGPointMake([self getCompViewX:compView addComp:addComp prevEdge:prevEdge], hostScrollView.frame.size.height / 2);
|
||||
prevEdge = compView.frame.origin.x + compView.frame.size.width;
|
||||
|
Loading…
x
Reference in New Issue
Block a user