1
0
Fork 0
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ddwrt_monitor/DDWRT_MonitorAppDelegate.m

633 lines
20 KiB

//
// 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:speedOut], [self stringFromFileSize:speedIn]] ];
}
_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];
[menuClientsConnections setTitle:[NSString stringWithFormat:@"%@ Connection%@", ipconn, ([ipconn isEqualToString:@"1"] ? @"" : @"s")]];
[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
{
[wrt_client getStatusUpdate:@"Status_Lan.live.asp" delegate:self callback:@selector(cbClientsRequest:)];
}
- (void) cbClientsRequest:(NSData*)data
{
NSString * clientsStringData;
NSString *stringData = [ [NSString alloc] initWithData:data encoding:NSASCIIStringEncoding ];
NSString *keyData = @"{arp_table::";
clientsStringData = [ stringData substringFromIndex:([stringData rangeOfString:keyData].location + [keyData length]) ];
clientsStringData = [ clientsStringData substringToIndex:[clientsStringData rangeOfString:@"}"].location ];
// Remove any white spaces
NSArray *parts = [clientsStringData componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSArray *filteredArray = [parts filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF != ''"]];
clientsStringData = [filteredArray componentsJoinedByString:@" "];
parts = nil;
filteredArray = nil;
// Remove any quotes
parts = [clientsStringData componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"\'"]];
filteredArray = [parts filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF != ''"]];
clientsStringData = [filteredArray componentsJoinedByString:@""];
NSArray *clientsData = [clientsStringData componentsSeparatedByString:@","];
long clientIndex;
NSMenu *clientMenu;
NSMenu *copyMenu;
NSMenuItem *copyMenuItem;
NSMenuItem *clientMenuItem;
NSMenuItem *clientItem;
unsigned long clientsCount = [clientsData count] / 4;
[menuClientsCount setTitle:[NSString stringWithFormat:@"%lu Active Client%@", clientsCount, (clientsCount > 1 ? @"s" : @"")]];
for (clientIndex = 0; clientIndex < [clientsData count]; clientIndex+=4) {
NSLog(@"Client: %@ IP: %@ MAC: %@ Connections: %@",
[clientsData objectAtIndex:clientIndex],
[clientsData objectAtIndex:clientIndex+1],
[clientsData objectAtIndex:clientIndex+2],
[clientsData objectAtIndex:clientIndex+3]);
clientMenu = [[NSMenu alloc] init];
// Hostname
copyMenu = [[NSMenu alloc] init];
copyMenuItem = [[NSMenuItem alloc] initWithTitle:@"Copy" action:@selector(copyParentMenuTitle:) keyEquivalent:@""];
[copyMenuItem setEnabled:true];
[copyMenuItem setTarget:self];
[copyMenu addItem:copyMenuItem];
clientMenuItem = [[NSMenuItem alloc] initWithTitle:[clientsData objectAtIndex:clientIndex] action:nil keyEquivalent:@""];
[clientMenuItem setSubmenu:copyMenu];
[clientMenu addItem:clientMenuItem];
// IP
copyMenu = [[NSMenu alloc] init];
copyMenuItem = [[NSMenuItem alloc] initWithTitle:@"Copy" action:@selector(copyParentMenuTitle:) keyEquivalent:@""];
[copyMenuItem setEnabled:true];
[copyMenuItem setTarget:self];
[copyMenu addItem:copyMenuItem];
clientMenuItem = [[NSMenuItem alloc] initWithTitle:[clientsData objectAtIndex:(clientIndex+1)] action:nil keyEquivalent:@""];
[clientMenuItem setSubmenu:copyMenu];
[clientMenu addItem:clientMenuItem];
// MAC
copyMenu = [[NSMenu alloc] init];
copyMenuItem = [[NSMenuItem alloc] initWithTitle:@"Copy" action:@selector(copyParentMenuTitle:) keyEquivalent:@""];
[copyMenuItem setEnabled:true];
[copyMenuItem setTarget:self];
[copyMenu addItem:copyMenuItem];
clientMenuItem = [[NSMenuItem alloc] initWithTitle:[clientsData objectAtIndex:(clientIndex+2)] action:nil keyEquivalent:@""];
[clientMenuItem setSubmenu:copyMenu];
[clientMenu addItem:clientMenuItem];
// Connections
clientMenuItem = [[NSMenuItem alloc] initWithTitle:[clientsData objectAtIndex:(clientIndex+3)] action:nil keyEquivalent:@""];
[clientMenu addItem:clientMenuItem];
clientItem = [[NSMenuItem alloc] initWithTitle:[clientsData objectAtIndex:clientIndex] action:nil keyEquivalent:@""];
[clientItem setSubmenu:clientMenu];
[menuClients addItem:clientItem];
}
}
- (IBAction) copyParentMenuTitle:(id)sender
{
NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard];
[pasteBoard declareTypes:[NSArray arrayWithObjects:NSStringPboardType, nil] owner: nil];
[pasteBoard setString:[[sender parentItem] title] forType:NSStringPboardType];
}
- (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