4 * Rendezvous network controller
6 * Original Author : Kent Sutherland <ksuther@ithinksw.com>
7 * Responsibility : Kent Sutherland <ksuther@ithinksw.com>
9 * Copyright (c) 2003 iThink Software.
14 #import "NetworkController.h"
15 #import "MainController.h"
16 #import "NetworkObject.h"
17 #import "PreferencesController.h"
18 #import <ITFoundation/ITDebug.h>
19 #import <ITFoundation/ITFoundation.h>
21 static NetworkController *sharedController;
23 @implementation NetworkController
25 + (NetworkController *)sharedController
27 return sharedController;
32 if ( (self = [super init]) ) {
33 sharedController = self;
34 browser = [[NSNetServiceBrowser alloc] init];
35 [browser setDelegate:self];
36 rootObject = [[NetworkObject alloc] init];
37 serverPort = [[NSSocketPort alloc] initWithTCPPort:SERVER_PORT];
46 [serverConnection release];
52 [clientProxy release];
53 [remoteServices release];
60 - (void)startRemoteServerSearch
62 [browser searchForServicesOfType:@"_mttp._tcp." inDomain:@""];
63 [remoteServices release];
64 remoteServices = [[NSMutableArray alloc] init];
67 - (void)stopRemoteServerSearch
72 - (void)setServerStatus:(BOOL)status
74 if (!serverOn && status) {
75 NSString *name = [[NSUserDefaults standardUserDefaults] stringForKey:@"sharedPlayerName"];
80 serverConnection = [[NSConnection alloc] initWithReceivePort:serverPort
82 [serverConnection setRootObject:rootObject];
83 [rootObject makeValid];
84 [serverConnection registerName:@"ITMTPlayerHost"];
86 [serverConnection setRootObject:nil];
87 [serverConnection release];
89 ITDebugLog(@"Error starting server!");
92 ITDebugLog(@"Started server.");
94 name = @"MenuTunes Shared Player";
96 service = [[NSNetService alloc] initWithDomain:@""
100 fullPass = [[NSUserDefaults standardUserDefaults] dataForKey:@"sharedPlayerPassword"];
101 if ([fullPass length]) {
102 [fullPass getBytes:&buffer range:NSMakeRange(6, 4)];
103 [serverPass release];
104 serverPass = [[NSData alloc] initWithBytes:&buffer length:strlen(&buffer)];
110 ITDebugLog(@"Server service published.");
111 } else if (serverOn && !status && [serverConnection isValid]) {
115 [rootObject invalidate];
116 [serverConnection registerName:nil];
117 [serverConnection invalidate];
118 //[serverConnection setRootObject:nil];
119 //[[serverConnection sendPort] autorelease];
120 [serverConnection release];
121 ITDebugLog(@"Stopped server.");
126 - (int)connectToHost:(NSString *)host
128 NSData *fullPass = [[NSUserDefaults standardUserDefaults] dataForKey:@"connectPassword"];
129 unsigned char buffer;
130 ITDebugLog(@"Connecting to host: %@", host);
131 [remoteHost release];
132 remoteHost = [host copy];
134 [fullPass getBytes:&buffer range:NSMakeRange(6, 4)];
135 [clientPass release];
136 clientPass = [[NSData alloc] initWithBytes:&buffer length:strlen(&buffer)];
141 clientPort = [[NSSocketPort alloc] initRemoteWithTCPPort:SERVER_PORT
143 clientConnection = [[NSConnection connectionWithReceivePort:nil sendPort:clientPort] retain];
144 [clientConnection setReplyTimeout:10];
145 clientProxy = [[clientConnection rootProxy] retain];
146 connectedToServer = YES;
148 [clientConnection release];
149 [clientPort release];
150 ITDebugLog(@"Connection to host failed: %@", host);
155 ITDebugLog(@"Null proxy! Couldn't connect!");
160 if ([clientProxy requiresPassword]) {
161 ITDebugLog(@"Server requires password.");
162 //Check to see if a password is set in defaults
163 if ([[NSUserDefaults standardUserDefaults] dataForKey:@"connectPassword"] == nil) {
164 ITDebugLog(@"Asking for password.");
165 if (![[PreferencesController sharedPrefs] showPasswordPanel]) {
166 ITDebugLog(@"Giving up connection attempt.");
173 ITDebugLog(@"Sending password.");
174 while (![clientProxy sendPassword:[[NSUserDefaults standardUserDefaults] dataForKey:@"connectPassword"]]) {
175 ITDebugLog(@"Invalid password!");
176 if (![[PreferencesController sharedPrefs] showInvalidPasswordPanel]) {
177 ITDebugLog(@"Giving up connection attempt.");
184 ITDebugLog(@"Connected to host: %@", host);
185 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(disconnect) name:NSConnectionDidDieNotification object:clientConnection];
191 ITDebugLog(@"Disconnecting from host.");
192 connectedToServer = NO;
193 [remoteHost release];
195 [[NSNotificationCenter defaultCenter] removeObserver:self];
196 [clientProxy release];
197 [clientConnection release];
201 - (BOOL)checkForServerAtHost:(NSString *)host
203 NSData *fullPass = [[NSUserDefaults standardUserDefaults] dataForKey:@"connectPassword"];
204 unsigned char buffer;
205 NSConnection *testConnection = nil;
206 NSSocketPort *testPort = nil;
207 NetworkObject *tempProxy;
209 ITDebugLog(@"Checking for shared remote at %@.", host);
211 [fullPass getBytes:&buffer range:NSMakeRange(6, 4)];
212 [clientPass release];
213 clientPass = [[NSData alloc] initWithBytes:&buffer length:strlen(&buffer)];
219 testPort = [[NSSocketPort alloc] initRemoteWithTCPPort:SERVER_PORT
221 testConnection = [[NSConnection connectionWithReceivePort:nil sendPort:testPort] retain];
222 [testConnection setReplyTimeout:5];
223 [testConnection setRequestTimeout:5];
224 tempProxy = (NetworkObject *)[testConnection rootProxy];
225 [tempProxy serverName];
226 valid = [tempProxy isValid];
228 ITDebugLog(@"Connection to host failed: %@", host);
229 [testConnection release];
235 ITDebugLog(@"Null proxy! Couldn't connect!");
236 [testConnection release];
240 [testConnection release];
245 - (void)resetServerName
247 if ([self isServerOn]) {
250 service = [[NSNetService alloc] initWithDomain:@""
252 name:[[NSUserDefaults standardUserDefaults] stringForKey:@"sharedPlayerName"]
262 - (BOOL)isClientConnected
264 return clientConnected;
267 - (BOOL)isConnectedToServer
269 return connectedToServer;
272 - (NSString *)remoteHost
277 - (NetworkObject *)networkObject
282 - (NSArray *)remoteServices
284 return remoteServices;
287 - (void)netServiceBrowser:(NSNetServiceBrowser *)aNetServiceBrowser didFindService:(NSNetService *)aNetService moreComing:(BOOL)moreComing
289 ITDebugLog(@"Found service named %@.", [aNetService name]);
290 [remoteServices addObject:aNetService];
291 [aNetService setDelegate:self];
292 //Figure out if it responds to the 10.4 method
293 if ([aNetService respondsToSelector:@selector(resolveWithTimeout:)]) {
294 (void)[aNetService resolveWithTimeout:5.0];
296 [aNetService resolve];
299 [[NSNotificationCenter defaultCenter] postNotificationName:@"ITMTFoundNetService" object:nil];
303 - (void)netServiceBrowser:(NSNetServiceBrowser *)aNetServiceBrowser didRemoveService:(NSNetService*)aNetService moreComing:(BOOL)moreComing
305 ITDebugLog(@"Removed service named %@.", [aNetService name]);
306 [remoteServices removeObject:aNetService];
308 [[NSNotificationCenter defaultCenter] postNotificationName:@"ITMTFoundNetService" object:nil];
312 - (void)netServiceDidResolveAddress:(NSNetService *)sender
314 ITDebugLog(@"Resolved service named %@.", [sender name]);
315 [[NSNotificationCenter defaultCenter] postNotificationName:@"ITMTFoundNetService" object:nil];
316 if ([[NSUserDefaults standardUserDefaults] boolForKey:@"useSharedPlayer"] && !connectedToServer) {
317 [[MainController sharedController] checkForRemoteServerAndConnectImmediately:NO];
322 - (void)netServiceWillResolve:(NSNetService *)sender
324 ITDebugLog(@"Resolving service named %@.", [sender name]);
327 - (void)netService:(NSNetService *)sender didNotResolve:(NSDictionary *)errorDict
329 ITDebugLog(@"Error resolving service %@.", errorDict);