123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454 |
- #import "ATVDeviceController.h"
- #import <sys/types.h>
- #import <sys/socket.h>
- #import <netinet/in.h>
- #import <arpa/inet.h>
- #import "AppDelegate.h"
- #define APP_DELEGATE (AppDelegate *)[[NSApplication sharedApplication] delegate]
- @implementation ATVDeviceController
- @synthesize deviceController, theComboBox, delegate;
- - (NSString *)input: (NSString *)prompt defaultValue: (NSString *)defaultValue {
- NSAlert *alert = [NSAlert alertWithMessageText: prompt
- defaultButton:@"OK"
- alternateButton:@"Cancel"
- otherButton:nil
- informativeTextWithFormat:@""];
-
- NSTextField *input = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 200, 24)];
- [input setStringValue:defaultValue];
- [alert setAccessoryView:input];
- NSInteger button = [alert runModal];
- if (button == NSAlertDefaultReturn) {
- [input validateEditing];
- NSString *inputString = [input stringValue];
- return inputString;
- } else if (button == NSAlertAlternateReturn) {
- return nil;
- } else {
-
- NSAssert1(NO, @"Invalid input dialog button %d", button);
- //[input autorelease];
- return nil;
- }
- }
- - (IBAction)menuItemSelected:(id)sender
- {
- NSLog(@"sender: %@", sender);
- if (sender == nil)
- {
- return;
- }
- [APP_DELEGATE setAtvAvailable:NO];
- [[APP_DELEGATE progressInd] startAnimation:nil];
- NSInteger index = [sender indexOfSelectedItem];
-
- NSInteger itemCount = [sender numberOfItems];
-
- if (index == 0)
- {
- [APP_DELEGATE setAtvAvailable:FALSE];
- [APP_DELEGATE resetServerSettings];
-
- return;
- }
-
- if (index == itemCount-1)
- {
- //[sender setEditable:TRUE];
-
- NSString *output = [self input:@"Enter an Apple TV name or IP address" defaultValue:@""];
- [APP_DELEGATE setAtvAvailable:TRUE];
- [DEFAULTS setObject:output forKey:@"appleTVHost"];
- return;
-
- } else {
-
- // [sender setEditable:FALSE];
- }
-
- dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND
- , 0), ^{
- NSNetService * clickedService = [services objectAtIndex:index];
- NSDictionary *finalDict = [self stringDictionaryFromService:clickedService];
- NSLog(@"finalDict: %@", finalDict);
- if ([[finalDict allKeys] count] > 0)
- {
- NSString *model = [finalDict objectForKey:@"model"];
- if ([model isEqualToString:@"AppleTV3,1"])
- {
- dispatch_async(dispatch_get_main_queue(), ^{
- [sender selectItemAtIndex:0];
- [APP_DELEGATE setAtvAvailable:FALSE];
- [APP_DELEGATE showATVWarning];
- [[APP_DELEGATE progressInd] stopAnimation:nil];
- });
-
- } else {
- NSString *ip;
- //int port;
- struct sockaddr_in *addr;
-
- addr = (struct sockaddr_in *) [[[clickedService addresses] objectAtIndex:0]
- bytes];
- ip = [NSString stringWithUTF8String:(char *) inet_ntoa(addr->sin_addr)];
-
- NSString *fullIP = [NSString stringWithFormat:@"%@:%i", ip, 22];
-
- //[APP_DELEGATE setAtvAvailable:TRUE];
- [DEFAULTS setObject:fullIP forKey:ATV_HOST];
-
- [APP_DELEGATE setStatusText:@"Checking device for jailbreak, please wait..."];
- NSLog(@"ATVADDRESS: %@", APPLE_TV_ADDRESS);
- BOOL jailbroken = [APP_DELEGATE isJailbroken];
-
- //hacky check here to see if its jailbroken
- dispatch_async(dispatch_get_main_queue(), ^{
- NSLog(@"is jailbroken: %lu", jailbroken);
- if (jailbroken == FALSE){
- [APP_DELEGATE showNotJailbrokenWarning];
- [DEFAULTS removeObjectForKey:ATV_HOST];
- [DEFAULTS removeObjectForKey:@"selectedValue"];
- [APP_DELEGATE setStatusText:@"Device is not jailbroken! :("];
- [[APP_DELEGATE progressInd] stopAnimation:nil];
- } else {
- [APP_DELEGATE setStatusText:@"Device is jailbroken!"];
- [APP_DELEGATE setAtvAvailable:YES];
- [[APP_DELEGATE progressInd] stopAnimation:nil];
- [APP_DELEGATE setDeviceDict:finalDict];
- }
-
- });
-
- }
- }
- });
-
-
- }
- - (NSString *)convertedName:(NSString *)inputName
- {
-
-
- NSMutableString *fixedNetLabel = [NSMutableString stringWithString:[inputName stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@".#,<>/?\'\\\[]{}+=-~`\";:"]]];
- //NSLog(@"fixedNetLabel: %@", fixedNetLabel);
- [fixedNetLabel replaceOccurrencesOfString:@" " withString:@"-" options:0 range:NSMakeRange(0, [fixedNetLabel length])];
- //int nameLength = [fixedNetLabel length];
- //fixedNetLabel = [fixedNetLabel substringToIndex:(nameLength-1)];
- return [NSString stringWithString:fixedNetLabel];
- }
- - (NSString *)fixedName:(NSString *)inputName
- {
- NSInteger nameLength = [inputName length];
- NSString *newName = [inputName substringToIndex:(nameLength-1)];
- return newName;
- }
- - (NSDictionary *)stringDictionaryFromService:(NSNetService *)theService
- {
- NSData *txtRecordDict = [theService TXTRecordData];
-
- NSDictionary *theDict = [NSNetService dictionaryFromTXTRecordData:txtRecordDict];
- NSMutableDictionary *finalDict = [[NSMutableDictionary alloc] init];
- NSArray *keys = [theDict allKeys];
- for (NSString *theKey in keys)
- {
- NSString *currentString = [[NSString alloc] initWithData:[theDict valueForKey:theKey] encoding:NSUTF8StringEncoding];
- [finalDict setObject:currentString forKey:theKey];
- }
- NSString *ip;
- int port;
- struct sockaddr_in *addr;
- if ([[theService addresses] count] == 0)
- {
- NSLog(@"no addresses resolved!?!?");
- return nil;
- }
- addr = (struct sockaddr_in *) [[[theService addresses] objectAtIndex:0]
- bytes];
- ip = [NSString stringWithUTF8String:(char *) inet_ntoa(addr->sin_addr)];
- port = ntohs(((struct sockaddr_in *)addr)->sin_port);
- //NSLog(@"ipaddress: %@", ip);
- //NSLog(@"port: %i", port);
-
- NSString *fullIP = [NSString stringWithFormat:@"%@:%i", ip, port];
- finalDict[@"fullIP"] = fullIP;
- finalDict[@"hostname"] = theService.hostName;
- return finalDict;
- }
- - (id)init {
-
- browser = [[NSNetServiceBrowser alloc] init];
- services = [NSMutableArray array];
- [browser setDelegate:self];
- //NSLog(@"awake from nib");
- // Passing in "" for the domain causes us to browse in the default browse domain
-
- [browser searchForServicesOfType:@"_airplay._tcp." inDomain:@""];
- // [hostNameField setStringValue:@""];
- self = [super init];
-
- NSDictionary *catv = [NSDictionary dictionaryWithObject:@"Choose Apple TV" forKey:@"name"];
- NSDictionary *theDict = [NSDictionary dictionaryWithObject:@"Other..." forKey:@"name"];
- [services addObject:catv];
- [services addObject:theDict];
- return self;
- }
- - (void)netServiceBrowserDidStopSearch:(NSNetServiceBrowser *)browser
- {
- //NSLog(@"%@ %s", self, _cmd);
- searching = NO;
- //[_parentObject endServices:services];
- [self updateUI];
-
- }
- - (void)updateUI
- {
- //NSLog(@"%@ %s", self, _cmd);
- if(searching)
-
- {
-
- // Update the user interface to indicate searching
-
- // Also update any UI that lists available services
-
- }
-
- else
-
- {
-
- NSLog(@"services: %@", services);
- // Update the user interface to indicate not searching
-
- }
-
- }
- - (void)netServiceBrowserWillSearch:(NSNetServiceBrowser *)browser
- {
- //NSLog(@"%@ %s", self, _cmd);
- searching = YES;
-
- [self updateUI];
-
- }
- // Error handling code
- - (void)handleError:(NSNumber *)error
- {
-
- NSLog(@"An error occurred. Error code = %d", [error intValue]);
-
- // Handle error here
-
- }
- - (BOOL)searching {
- return searching;
- }
- // This object is the delegate of its NSNetServiceBrowser object. We're only interested in services-related methods, so that's what we'll call.
- - (void)netServiceBrowser:(NSNetServiceBrowser *)aNetServiceBrowser didFindService:(NSNetService *)aNetService moreComing:(BOOL)moreComing {
-
- NSInteger servicesCount = [services count]-1;
-
- [services insertObject:aNetService atIndex:servicesCount];
- [aNetService setDelegate:self];
- [aNetService resolveWithTimeout:5.0];
-
- if(!moreComing) {
-
- [deviceController setContent:services];
-
- }
- }
- #if TARGET_OS_OSX
- /*
- - (NSString *)input: (NSString *)prompt defaultValue: (NSString *)defaultValue {
- NSAlert *alert = [NSAlert alertWithMessageText: prompt
- defaultButton:@"OK"
- alternateButton:@"Cancel"
- otherButton:nil
- informativeTextWithFormat:@""];
-
- NSTextField *input = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 200, 24)];
- [input setStringValue:defaultValue];
- [alert setAccessoryView:input];
- NSInteger button = [alert runModal];
- if (button == NSAlertDefaultReturn) {
- [input validateEditing];
- NSString *inputString = [input stringValue];
- return inputString;
- } else if (button == NSAlertAlternateReturn) {
- return nil;
- } else {
-
- NSAssert1(NO, @"Invalid input dialog button %d", button);
- return nil;
- }
- }
- */
- #endif
- - (void)netServiceBrowser:(NSNetServiceBrowser *)aNetServiceBrowser didRemoveService:(NSNetService *)aNetService moreComing:(BOOL)moreComing {
- [services removeObject:aNetService];
-
- if(!moreComing) {
-
- }
- }
- - (NSDictionary *)deviceDictionary {
- return deviceDictionary;
- }
- - (void)setDeviceDictionary:(NSDictionary *)value {
- if (deviceDictionary != value) {
-
- deviceDictionary = [value copy];
- }
- }
- //resolution stuff
- - (BOOL)addressesComplete:(NSArray *)addresses
- forServiceType:(NSString *)serviceType
- {
- // Perform appropriate logic to ensure that [netService addresses]
-
- if ([self.delegate respondsToSelector:@selector(servicesFound:)])
- {
- NSMutableArray *fullServices = [NSMutableArray new];
- for (NSNetService *service in services)
- {
- NSDictionary *fullDict = [self stringDictionaryFromService:service];
- if (fullDict != nil)
- [fullServices addObject:fullDict];
- }
-
- [self.delegate servicesFound:fullServices];
- }
-
-
- return YES;
-
- }
- // Sent when addresses are resolved
- - (void)netServiceDidResolveAddress:(NSNetService *)aNetService
- {
- NSDictionary *finalDict = [self stringDictionaryFromService:aNetService];
- if ([[finalDict allKeys] count] > 0)
- {
-
- NSString *model = [finalDict objectForKey:@"model"];
- if ([model isEqualToString:@"AppleTV5,3"])
- {
- //NSLog(@"should add service: %@", aNetService);
- // NSInteger servicesCount = [services count]-1;
-
- //[services insertObject:aNetService atIndex:servicesCount];
-
- } else {
- [services removeObject:aNetService];
-
- [deviceController setContent:services];
- }
- }
- /*
- if ([self addressesComplete:[netService addresses]
-
- forServiceType:[netService type]]) {
-
-
- }
- */
- }
- // Sent if resolution fails
- - (void)netService:(NSNetService *)netService
- didNotResolve:(NSDictionary *)errorDict
- {
- //NSLog(@"%@ %s", self, _cmd);
- [self handleError:[errorDict objectForKey:NSNetServicesErrorCode]];
-
- [services removeObject:netService];
-
- }
- #if TARGET_OS_OSX
- // This object is the data source of its NSTableView. servicesList is the NSArray containing all those services that have been discovered.
- - (int)numberOfRowsInTableView:(NSTableView *)theTableView {
- return [services count];
- }
- - (NSDictionary *)currentServiceDictionary {
- NSNetService * clickedService = [services objectAtIndex:[[self theComboBox] indexOfSelectedItem]];
-
- //NSLog(@"clickedService: %@" ,[self theComboBox]);
-
- return [self stringDictionaryFromService:clickedService];
- }
- - (id)tableView:(NSTableView *)theTableView objectValueForTableColumn:(NSTableColumn *)theColumn row:(int)rowIndex {
- NSString *fixedName = [[[[services objectAtIndex:rowIndex] name] componentsSeparatedByString:@"@"] lastObject];
- return fixedName;
- // return [[services objectAtIndex:rowIndex] name];
- }
- #endif
- @end
|