// // DDWRT_MonitorAppDelegate.m // DDWRT-Monitor // // Created by Matthieu Lalonde & Spike Grobstein on 11-05-27. // Copyleft 2011 Spurf CC BY-SH-NC. Some rights reserved. // #import "DDWRT_MonitorAppDelegate.h" @implementation DDWRT_MonitorAppDelegate //@synthesize window; //- (void)applicationDidFinishLaunching:(NSNotification *)aNotification - (void) awakeFromNib { // Insert code here to initialize your application [self showMenubar]; _wrtReachable = false; defaults = [NSUserDefaults standardUserDefaults]; // check if the app is configured yet if (![defaults boolForKey:@"configured"]) { [self initDefaults]; } NSLog(@"Reading defaults..."); [self readDefaults]; // initialize the client wrt_client = [[WRTStatusClient alloc] initWithHostname:hostname port:port protocol:protocol username:username password:password]; [wrt_client getConnectionStatus]; NSLog(@"Status %@ wan port: %@", ([wrt_client wrtReachable] ? @"Up" : @"Down"), [wrt_client getWanPort]); _readTimer = [NSTimer scheduledTimerWithTimeInterval:refreshTime+1 target:self selector:@selector(updateThroughput:) userInfo:nil repeats:YES]; [_readTimer fire]; //[self updateThroughput]; //WRTRequest *wrtr = [[WRTRequest alloc] init]; //[wrtr doRequest:self requestSelector:@selector(doUpdateStatus:) uri:@"Status_Router.live.asp"]; } - (void) dealloc { //[_readTimer invalidate]; [AppMenu release]; [_appMenu release]; [ConfigPanel release]; //[BandwidthViewer release]; [modalWindow release]; [super dealloc]; } - (void) initDefaults { NSLog(@"Creating new user defaults"); // do any other initialization you want to do here - e.g. the starting default values. [defaults setValue:@"http" forKey:@"protocol"]; [defaults setValue:@"192.168.1.1" forKey:@"hostname"]; [defaults setInteger:80 forKey:@"port"]; [defaults setValue:@"" forKey:@"username"]; [defaults setValue:@"" forKey:@"password"]; [defaults setBool:YES forKey:@"showMenuIcon"]; [defaults setBool:YES forKey:@"useBytes"]; [defaults setInteger:4 forKey:@"refreshTime"]; [defaults setBool:YES forKey:@"configured"]; // sync the defaults to disk //[defaults registerDefaults:appDefaults]; [defaults synchronize]; // TODO: Add modal alert "First launch" here... [self showConfigPanel:self]; } - (void) readDefaults { hostname = [defaults valueForKey:@"hostname"]; protocol = [defaults valueForKey:@"protocol"]; port = [defaults integerForKey:@"port"]; username = [defaults valueForKey:@"username"]; password = [defaults valueForKey:@"password"]; showMenuIcon = [defaults boolForKey:@"showMenuIcon"]; useBytes = [defaults boolForKey:@"useBytes"]; refreshTime = [defaults integerForKey:@"refreshTime"]; } - (void) writeDefaults { // do any other initialization you want to do here - e.g. the starting default values. [defaults setValue:hostname forKey:@"hostname"]; [defaults setValue:protocol forKey:@"protocol"]; [defaults setInteger:port forKey:@"port"]; [defaults setValue:username forKey:@"username"]; [defaults setValue:password forKey:@"password"]; [defaults setBool:showMenuIcon forKey:@"showMenuIcon"]; [defaults setBool:useBytes forKey:@"useBytes"]; [defaults setInteger:refreshTime forKey:@"refreshTime"]; // sync the defaults to disk //[defaults registerDefaults:appDefaults]; [defaults synchronize]; } - (void) terminate:(id)sender { [_readTimer invalidate]; [[NSUserDefaults standardUserDefaults] synchronize]; [self dealloc]; [[NSApplication sharedApplication] terminate:self]; } - (void) showMenubar { NSLog(@"Showing Menu Item"); NSStatusBar* bar = [NSStatusBar systemStatusBar]; _appMenu = [bar statusItemWithLength:NSVariableStatusItemLength]; [_appMenu retain]; //[self setMenubarText:@"000KB/s\n000KB/s"]; //BOOL showIcon = [[NSUserDefaults standardUserDefaults] boolForKey:@"showMenuIcon"]; //if (showIcon == true) { [self showMenubarIcon:false]; //} [_appMenu setHighlightMode:YES]; [_appMenu setMenu:AppMenu]; } - (void) hideMenubar { [_appMenu release]; _appMenu = nil; [AppMenu release]; AppMenu = nil; } - (void) showMenubarIcon:(BOOL)enabled { NSImage* icon = [NSImage imageNamed:(enabled == true ? @"MenuIcon" : @"MenuIconDisabled")]; [_appMenu setImage:icon]; [_appMenu setAlternateImage:nil]; [icon release]; } - (void) hideMenubarIcon { [_appMenu setImage:nil]; [_appMenu setAlternateImage:nil]; } - (void) setMenubarText:(NSString *)menubarText { // Todo set proper line height NSFontManager *fontManager = [NSFontManager sharedFontManager]; NSFont *menuFont = [fontManager fontWithFamily:@"Lucida Grande" traits:NSBoldFontMask weight:10 size:8]; NSDictionary *titleAttributes = [[NSDictionary alloc] initWithObjectsAndKeys:menuFont, NSFontAttributeName, [NSColor blackColor], NSForegroundColorAttributeName, nil]; NSAttributedString *menuTitle = [[NSAttributedString alloc] initWithString:menubarText attributes:titleAttributes]; [_appMenu setAttributedTitle:menuTitle]; [fontManager release]; [menuFont release]; [menuTitle release]; } - (void) showConfigPanel:(id)sender { [configFieldShowIcon setState:([defaults boolForKey:@"showMenuIcon"] ? 1 : 0)]; [configFieldUseBytes setState:([defaults boolForKey:@"useBytes"] ? 1 : 0)]; if (hostname != nil) { [configFieldHostname setStringValue:hostname]; } // TODO [configFieldPort setIntValue:[defaults integerForKey:@"port"]]; [configFieldRefresh setIntegerValue:[defaults integerForKey:@"refreshTime"]]; [configLabelRefresh setStringValue:[NSString stringWithFormat:@"%d s", ([defaults integerForKey:@"refreshTime"] + 1)]]; [ConfigPanel makeKeyAndOrderFront:nil]; } - (void) hideConfigPanel:(id)sender { /*NSString *hostname = [[NSUserDefaults standardUserDefaults] stringForKey:@"hostname"]; if (hostname == nil && [[sender title] isEqualToString:@"Cancel"]) { // TODO: Add modal alert "will quit if not configured" [self terminate:nil]; } */ [ConfigPanel orderOut:nil]; } - (void) showBandwidthViewer:(id)sender { //NSURLRequest *request = [[wrt_client requestForBandwidthViewerForInterface:[wrt_client getWanPort]] retain]; NSString *urlAddress = [NSString stringWithFormat:@"%@://%@:%@@%@:%d/graph_if.svg?%@", protocol, username, password, hostname, port, [wrt_client getWanPort]]; NSLog(@"Building request form %@", urlAddress); NSURL *url = [NSURL URLWithString:urlAddress]; NSURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: url]; [ [BandwidthViewerWebView mainFrame] loadRequest: [request autorelease] ]; [BandwidthViewer makeKeyAndOrderFront:nil]; } - (void) hideBandwidthViewer:(id)sender { [BandwidthViewer orderOut:nil]; [BandwidthViewer release]; } - (void) setConfigHostname:(id)sender { NSLog(@"%@", [sender title]); } - (IBAction) setConfigProtocol:(id)sender { NSLog(@"%@", [sender title]); if ([sender state] == NSOnState) { NSLog(@"Yes"); //NSLog(@"%s", [sender title]); } else { NSLog(@"No"); //NSLog(@"%s", [sender title]); } } - (void) setConfigPort:(id)sender { } - (void) setConfigRefresh:(id)sender { [configLabelRefresh setStringValue:[NSString stringWithFormat:@"%u s", ([sender integerValue] + 1)]]; } - (void) setConfigWan:(id)sender { } - (void) setConfigBytes:(id)sender { } - (void) setConfigIcon:(id)sender { } - (void) saveConfig:(id)sender { [configStateStatus startAnimation:nil]; [configStateStatus setHidden:false]; //WRTRequest *wrtr = [[WRTRequest alloc] init]; // TODO check that the request is actually successful hostname = [configFieldHostname stringValue]; [defaults setValue:hostname forKey:@"hostname"]; port = [configFieldPort intValue]; [defaults setInteger:port forKey:@"port"]; //NSLog(@"%d", [configFieldProtocol state]); //NSLog(@"%d", [configFieldProtocolHTTP state]); //NSLog(@"%d", [configFieldProtocolHTTPS state]); refreshTime = [configFieldRefresh integerValue]; [defaults setInteger:refreshTime forKey:@"refreshTime"]; [_readTimer invalidate]; _readTimer = nil; _readTimer = [NSTimer scheduledTimerWithTimeInterval:refreshTime+1 target:self selector:@selector(updateThroughput:) userInfo:nil repeats:YES]; [_readTimer fire]; useBytes = ([configFieldUseBytes state] == 1 ? true: false); [defaults setBool:useBytes forKey:@"useBytes"]; if ([configFieldShowIcon state] == NSOffState && [defaults boolForKey:@"showMenuIcon"] == true) { [self hideMenubarIcon]; } else if ([configFieldShowIcon state] == NSOnState && [defaults boolForKey:@"showMenuIcon"] == false) { [self showMenubarIcon:false]; } showMenuIcon = ([configFieldShowIcon state] == 1 ? true: false); [defaults setBool:showMenuIcon forKey:@"showMenuIcon"]; [configStateStatus stopAnimation:nil]; [configStateStatus setHidden:true]; [defaults synchronize]; [self hideConfigPanel:nil]; } - (void) updateThroughput:(NSTimer*)timer { NSLog(@"Status %@ wan port: %@", ([wrt_client wrtReachable] ? @"Up" : @"Down"), [wrt_client getWanPort]); if ([wrt_client wrtReachable] == true && _wrtReachable == false) { _wrtReachable = true; [self showMenubarIcon:true]; } else if ([wrt_client wrtReachable] == false && _wrtReachable == true) { _wrtReachable = false; [self showMenubarIcon:false]; } if (_wrtReachable == true) { [wrt_client getStatusUpdate:[NSString stringWithFormat:@"fetchif.cgi?%@", [wrt_client getWanPort]] delegate:self callback:@selector(throughputCallback:)]; //[wrt_client getStatusUpdate:@"Status_Router.live.asp" delegate:self callback:@selector(doUpdateStatus:)]; //[wrt_client getStatusUpdate:@"Status_Internet.live.asp" delegate:self callback:@selector(wanRequestCallback:)]; } //WRTRequest *wrtr = [[WRTRequest alloc] init]; //[wrtr doRequest:self requestSelector:@selector(throughputCallback:) uri:@"fetchif.cgi?ppp1"]; } - (void) throughputCallback:(NSData *)data { [wrt_client getStatusUpdate:@"Status_Router.live.asp" delegate:self callback:@selector(doUpdateStatus:)]; NSString *stringData = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; NSString *key = [NSString stringWithFormat:@"%@:", [wrt_client getWanPort]]; stringData = [stringData substringFromIndex:([stringData rangeOfString:key].location + [key length])]; NSArray *parts = [stringData componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; NSArray *filteredArray = [parts filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF != ''"]]; stringData = [filteredArray componentsJoinedByString:@" "]; NSArray *listItems = [stringData componentsSeparatedByString:@" "]; unsigned long long ifIn = strtoull([[listItems objectAtIndex:0] UTF8String], NULL, 0); unsigned long long ifOut = strtoull([[listItems objectAtIndex:8] UTF8String], NULL, 0); if (_lastInThroughput != 0) { unsigned long long diffIn = ifIn - _lastInThroughput; unsigned long long diffOut = ifOut - _lastOutThroughput; double speedIn = diffIn / ([NSDate timeIntervalSinceReferenceDate] - _lastDateThroughput); double speedOut = diffOut / ([NSDate timeIntervalSinceReferenceDate] - _lastDateThroughput); speedIn = round(2.2f * speedIn) / 2.2f; speedOut = round(2.2f * speedOut) / 2.2f; [self setMenubarText:[NSString stringWithFormat:@"%@s\n%@s", [self stringFromFileSize:speedIn], [self stringFromFileSize:speedOut]]]; } _lastDateThroughput = [NSDate timeIntervalSinceReferenceDate]; _lastInThroughput = ifIn; _lastOutThroughput = ifOut; } -(void)doUpdateStatus:(NSData *)data { NSString *stringData = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; NSString *ipconn = [wrt_client getKey:stringData key:@"ip_conntrack"]; NSString *wanip = [wrt_client getKey:stringData key:@"ipinfo"]; NSRange startRange = [wanip rangeOfString:@" "]; wanip = [wanip substringFromIndex:(startRange.location+1)]; NSString *uptime = [wrt_client getKey:stringData key:@"uptime"]; NSString *loadSplit = @", load average: "; NSString *load = [uptime substringFromIndex:[uptime rangeOfString:loadSplit].location+[loadSplit length]]; uptime = [uptime substringToIndex:[uptime rangeOfString:@", load"].location]; // Cut the load uptime = [uptime substringFromIndex:[uptime rangeOfString:@" "].location+1]; // Trim uptime = [uptime stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:[[uptime substringToIndex:1] uppercaseString]]; // UCFirst [menuWanIP setTitle:wanip]; [menuUptime setTitle:uptime]; [menuLoad setTitle:load]; [menuLoad setHidden:false]; [menuConnections setTitle:[NSString stringWithFormat:@"Connections: %@", ipconn]]; [wrt_client getStatusUpdate:@"Status_Internet.live.asp" delegate:self callback:@selector(wanRequestCallback:)]; } - (void) refreshMenu:(id)sender { } - (void) refreshSystemMenu:(id)sender { } - (void) refreshWanMenu:(id)sender { NSLog(@"Refreshing Wan Menu"); //WRTRequest *wrtr = [[WRTRequest alloc] init]; //[wrtr doRequest:self requestSelector:@selector(wanRequestCallback:) uri:@"Status_Internet.live.asp"]; } - (void) wanRequestCallback:(NSData *)data { NSString *stringData = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; NSString *wanStatus = [wrt_client getKey:stringData key:@"wan_status"]; NSString *wanName = [wrt_client getKey:stringData key:@"wan_shortproto"]; if ([wanName isEqualToString:@"pppoe"] == true) { wanName = @"PPPoE"; } else if ([wanName isEqualToString:@"static"] == true) { wanName = @"Static"; } else { wanName = [wanName uppercaseString]; } wanStatus = [wanStatus substringToIndex:[wanStatus rangeOfString:@"&"].location]; [menuWanStatus setTitle:[NSString stringWithFormat:@"%@ %@", wanName, wanStatus]]; /* if ([_appMenu image] != nil) { [self showMenubarIcon:[wanStatus isEqualToString:@"Connected"]]; } */ NSString *wanUptime = [wrt_client getKey:stringData key:@"wan_uptime"]; if ([wanStatus isEqualToString:@"Connected"] == true) { [menuWanUptime setTitle:wanUptime]; [menuWanUptime setHidden:false]; [menuWanSeparator setHidden:false]; [menuWanBandwidthGraph setEnabled:true]; [menuWanTrafficIn setHidden:false]; [menuWanTrafficOut setHidden:false]; } else { [menuWanUptime setHidden:true]; [menuWanSeparator setHidden:true]; [menuWanBandwidthGraph setEnabled:false]; [menuWanTrafficIn setHidden:true]; [menuWanTrafficOut setHidden:true]; } NSString *trafficIn = [wrt_client getKey:stringData key:@"ttraff_in"]; NSString *trafficOut = [wrt_client getKey:stringData key:@"ttraff_out"]; trafficIn = [self stringFromFileSize:([trafficIn longLongValue] * 1024 * 1024)]; trafficOut = [self stringFromFileSize:([trafficOut longLongValue] * 1024 * 1024)]; [menuWanTrafficIn setTitle:[NSString stringWithFormat:@"In: %@", trafficIn]]; [menuWanTrafficOut setTitle:[NSString stringWithFormat:@"Out: %@", trafficOut]]; NSString *wanDNS0 = [wrt_client getKey:stringData key:@"wan_dns0"]; NSString *wanDNS1 = [wrt_client getKey:stringData key:@"wan_dns1"]; NSString *wanDNS2 = [wrt_client getKey:stringData key:@"wan_dns2"]; if ([wanDNS0 length] > 0) { [menuWanDNS setEnabled:true]; [menuWanDNSItem0 setTitle: wanDNS0]; [menuWanDNSItem0 setHidden:false]; } if ([wanDNS1 length] > 0) { [menuWanDNS setEnabled:true]; [menuWanDNSItem1 setTitle: wanDNS1]; [menuWanDNSItem1 setHidden:false]; } if ([wanDNS2 length] > 0) { [menuWanDNS setEnabled:true]; [menuWanDNSItem2 setTitle: wanDNS2]; [menuWanDNSItem2 setHidden:false]; } [stringData release]; } - (void) refreshClientsMenu:(id)sender { //[self updateThroughput:nil]; } - (NSString *) stringFromFileSize:(unsigned long long)theSize { double floatSize = theSize; if (theSize<1023) return([NSString stringWithFormat:@"%qx bytes",theSize]); floatSize = floatSize / 1024; if (floatSize<1023) return([NSString stringWithFormat:@"%1.1f KiB",floatSize]); floatSize = floatSize / 1024; if (floatSize<1023) return([NSString stringWithFormat:@"%1.1f MiB",floatSize]); floatSize = floatSize / 1024; if (floatSize<1023) return([NSString stringWithFormat:@"%1.1f GiB",floatSize]); floatSize = floatSize / 1024; return([NSString stringWithFormat:@"%1.1f TiB",floatSize]); } - (void) connection:(NSURLConnection*)connection didReceiveData:(NSData*)data { NSLog(@"Delegate Received: %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); } @end