implemented wake on lan

This commit is contained in:
Diego Waxemberg
2015-01-02 19:15:47 -05:00
parent a52b20ee52
commit ee61dc9a59
4 changed files with 133 additions and 6 deletions

View File

@@ -29,6 +29,8 @@
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 */; };
FB4678FF1A565DAC00377732 /* WakeOnLanManager.m in Sources */ = {isa = PBXBuildFile; fileRef = FB4678FE1A565DAC00377732 /* WakeOnLanManager.m */; };
FB4679011A57048000377732 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB4679001A57048000377732 /* CoreFoundation.framework */; };
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 */; };
@@ -112,6 +114,9 @@
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>"; };
FB4678FD1A565DAC00377732 /* WakeOnLanManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WakeOnLanManager.h; sourceTree = "<group>"; };
FB4678FE1A565DAC00377732 /* WakeOnLanManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WakeOnLanManager.m; sourceTree = "<group>"; };
FB4679001A57048000377732 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
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>"; };
@@ -262,6 +267,7 @@
FB290CF819B2C406004C83CF /* CoreData.framework in Frameworks */,
FB290CF619B2C406004C83CF /* UIKit.framework in Frameworks */,
FB290CF219B2C406004C83CF /* Foundation.framework in Frameworks */,
FB4679011A57048000377732 /* CoreFoundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -309,6 +315,7 @@
FB290CF019B2C406004C83CF /* Frameworks */ = {
isa = PBXGroup;
children = (
FB4679001A57048000377732 /* CoreFoundation.framework */,
FBD349571A003F05002D2A60 /* libsqlite3.dylib */,
FB89468F19F6AFB800339C8A /* libs */,
FB7E794319C8B71B00A15F68 /* libiconv.dylib */,
@@ -415,6 +422,8 @@
FBD3494219FC9C04002D2A60 /* AppManager.m */,
FB4678F81A55FFAD00377732 /* DiscoveryManager.h */,
FB4678F91A55FFAD00377732 /* DiscoveryManager.m */,
FB4678FD1A565DAC00377732 /* WakeOnLanManager.h */,
FB4678FE1A565DAC00377732 /* WakeOnLanManager.m */,
);
path = Network;
sourceTree = "<group>";
@@ -759,6 +768,7 @@
FB89463419F646E200339C8A /* Utils.m in Sources */,
FBDE86E619F82297001C18A8 /* UIAppView.m in Sources */,
FB89462F19F646E200339C8A /* Connection.m in Sources */,
FB4678FF1A565DAC00377732 /* WakeOnLanManager.m in Sources */,
FB89462919F646E200339C8A /* mkcert.c in Sources */,
FBDE86E019F7A837001C18A8 /* UIComputerView.m in Sources */,
FBDE86E919F82315001C18A8 /* App.m in Sources */,

View File

@@ -0,0 +1,16 @@
//
// WakeOnLanManager.h
// Limelight
//
// Created by Diego Waxemberg on 1/2/15.
// Copyright (c) 2015 Limelight Stream. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "Host.h"
@interface WakeOnLanManager : NSObject
+ (void) wakeHost:(Host*)host;
@end

View File

@@ -0,0 +1,82 @@
//
// WakeOnLanManager.m
// Limelight
//
// Created by Diego Waxemberg on 1/2/15.
// Copyright (c) 2015 Limelight Stream. All rights reserved.
//
#import "WakeOnLanManager.h"
#import "Utils.h"
#import <CoreFoundation/CoreFoundation.h>
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>
@implementation WakeOnLanManager
static const int numPorts = 5;
static const int ports[numPorts] = {7, 9, 47998, 47999, 48000};
+ (void) wakeHost:(Host*)host {
NSData* wolPayload = [WakeOnLanManager createPayload:host];
CFDataRef dataPayload = CFDataCreate(kCFAllocatorDefault, [wolPayload bytes], [wolPayload length]);
CFSocketRef wolSocket = CFSocketCreate(kCFAllocatorDefault, PF_INET, SOCK_DGRAM, IPPROTO_UDP, 0, NULL, NULL);
if (!wolSocket) {
NSLog(@"Failed to create WOL socket");
return;
}
NSLog(@"WOL socket created");
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_len = sizeof(addr);
for (int i = 0; i < 2; i++) {
// try all ip addresses
if (i == 0) {
inet_aton([host.localAddress UTF8String], &addr.sin_addr);
} else {
inet_aton([host.externalAddress UTF8String], &addr.sin_addr);
}
CFDataRef dataAddress = CFDataCreate(kCFAllocatorDefault, (unsigned char*)&addr, sizeof(addr));
// try all ports
for (int j = 0; j < numPorts; j++) {
addr.sin_port = htons(ports[j]);
NSLog(@"Sending WOL packet");
CFSocketSendData(wolSocket, dataAddress, dataPayload, 0);
}
CFRelease(dataAddress);
}
CFRelease(dataPayload);
}
+ (NSData*) createPayload:(Host*)host {
NSMutableData* payload = [[NSMutableData alloc] initWithCapacity:102];
// 6 bytes of FF
UInt8 header = 0xFF;
for (int i = 0; i < 6; i++) {
[payload appendBytes:&header length:1];
}
// 16 repitiions of MAC address
NSData* macAddress = [self macStringToBytes:host.mac];
for (int j = 0; j < 16; j++) {
[payload appendData:macAddress];
}
return payload;
}
+ (NSData*) macStringToBytes:(NSString*)mac {
NSString* macString = [mac stringByReplacingOccurrencesOfString:@":" withString:@""];
NSLog(@"MAC: %@", macString);
return [Utils hexToBytes:macString];
}
@end

View File

@@ -18,6 +18,7 @@
#import "SettingsViewController.h"
#import "DataManager.h"
#import "Settings.h"
#import "WakeOnLanManager.h"
@implementation MainFrameViewController {
NSOperationQueue* _opQueue;
@@ -115,12 +116,30 @@ static StreamConfiguration* streamConfig;
- (void)hostLongClicked:(Host *)host {
NSLog(@"Long clicked host: %@", host.name);
UIAlertController* longClickAlert = [UIAlertController alertControllerWithTitle:host.name message:@"" preferredStyle:UIAlertControllerStyleActionSheet];
[longClickAlert addAction:[UIAlertAction actionWithTitle:@"Unpair" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
HttpManager* hMan = [[HttpManager alloc] initWithHost:host.address uniqueId:_uniqueId deviceName:deviceName cert:_cert];
[hMan executeRequestSynchronously:[hMan newUnpairRequest]];
});
}]];
if (host.online) {
[longClickAlert addAction:[UIAlertAction actionWithTitle:@"Unpair" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
HttpManager* hMan = [[HttpManager alloc] initWithHost:host.address uniqueId:_uniqueId deviceName:deviceName cert:_cert];
[hMan executeRequestSynchronously:[hMan newUnpairRequest]];
});
}]];
} else {
[longClickAlert addAction:[UIAlertAction actionWithTitle:@"Wake" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){
UIAlertController* wolAlert = [UIAlertController alertControllerWithTitle:@"Wake On Lan" message:@"" preferredStyle:UIAlertControllerStyleAlert];
[wolAlert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];
if (host.pairState != PairStatePaired) {
wolAlert.message = @"Cannot wake host because you are not paired";
} else if (host.mac == nil || [host.mac isEqualToString:@"00:00:00:00:00:00"]) {
wolAlert.message = @"Host MAC unknown, unable to send WOL Packet";
} else {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[WakeOnLanManager wakeHost:host];
});
wolAlert.message = @"Sent WOL Packet";
}
[self presentViewController:wolAlert animated:YES completion:nil];
}]];
}
[longClickAlert addAction:[UIAlertAction actionWithTitle:@"Remove Host" style:UIAlertActionStyleDestructive handler:^(UIAlertAction* action) {
@synchronized(hostList) {
[hostList removeObject:host];