// // BonjourListener.m // Mini Cidney // // Created by Chris Karr on 1/13/08. // Copyright 2008 __MyCompanyName__. All rights reserved. // #import "BonjourListener.h" #import #import "Caller.h" #import "Dispatcher.h" #define PORT 31264 #define SERVICE @"_cidney._tcp." @implementation BonjourListener @synthesize connection; @synthesize port; @synthesize bonjour; @synthesize name; @synthesize number; @synthesize imageData; - (NSString *) normalizePhoneNumber:(NSString *) phoneNumber { NSMutableString * newNumber = [NSMutableString stringWithString:phoneNumber]; [newNumber replaceOccurrencesOfString:@"\r" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange (0, [newNumber length])]; [newNumber replaceOccurrencesOfString:@"\n" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange (0, [newNumber length])]; [newNumber replaceOccurrencesOfString:@"-" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange (0, [newNumber length])]; [newNumber replaceOccurrencesOfString:@" " withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange (0, [newNumber length])]; [newNumber replaceOccurrencesOfString:@"(" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange (0, [newNumber length])]; [newNumber replaceOccurrencesOfString:@")" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange (0, [newNumber length])]; [newNumber replaceOccurrencesOfString:@"+" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange (0, [newNumber length])]; return newNumber; } - (ABPerson *) findPersonByNumber:(NSString *) phoneNumber { number = [self normalizePhoneNumber:phoneNumber]; ABAddressBook * ab = [ABAddressBook sharedAddressBook]; for (ABPerson * person in [ab people]) { ABMutableMultiValue * phones = [person valueForProperty:kABPhoneProperty]; int i = 0; for (i = 0; i < [phones count]; i++) { NSString * phone = [self normalizePhoneNumber:[phones valueAtIndex:i]]; if ([phone rangeOfString:phoneNumber].location != NSNotFound) return person; } } return nil; } - (NSString *) machineName { CFStringRef nameRef; NSString * computerName; nameRef = CSCopyMachineName (); computerName = [NSString stringWithString:(NSString *) nameRef]; CFRelease (nameRef); return computerName; } - (void) stopServer { [self.connection release]; self.connection = nil; [self.port release]; self.port = nil; [self.bonjour release]; self.bonjour = nil; } - (void) startServer { if (self.connection != nil || self.port != nil || self.bonjour != nil) [self stopServer]; self.port = [[NSSocketPort alloc] initWithTCPPort:PORT]; self.connection = [[NSConnection alloc] initWithReceivePort:port sendPort:nil]; [self.connection setRootObject:self]; self.bonjour = [[NSNetService alloc] initWithDomain:@"local" type:SERVICE name:[self machineName] port:PORT]; [self.bonjour publish]; } - (void) awakeFromNib { NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults]; if ([defaults boolForKey:@"Bonjour Listener"]) [self startServer]; [defaults addObserver:self forKeyPath:@"Bonjour Listener" options:NSKeyValueObservingOptionNew context:NULL]; } - (void) observeValueForKeyPath:(NSString *) keyPath ofObject:(id) object change:(NSDictionary *) change context:(void *) context { NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults]; if ([defaults boolForKey:@"Bonjour Listener"]) [self startServer]; else [self stopServer]; } - (NSString *) incomingCaller:(NSString *) newName number:(NSString *) newNumber image:(NSData *) newImageData { ABPerson * person = [self findPersonByNumber:newNumber]; Caller * dict = [Caller dictionary]; [dict setValue:newName forKey:NAME_KEY]; [dict setValue:newNumber forKey:NUMBER_KEY]; [dict setValue:person forKey:PERSON_KEY]; [dict setValue:[NSNumber numberWithBool:YES] forKey:BONJOUR_KEY]; [[NSNotificationCenter defaultCenter] postNotificationName:INCOMING_CALL object:self userInfo:dict]; return @"ok"; } @end