RAAAAAHHHHHHHHHHH NETWORK MENUTOOOONS!
[MenuTunes.git] / NetworkController.m
1 /*
2  *      MenuTunes
3  *  NetworkController
4  *    Rendezvous network controller
5  *
6  *  Original Author : Kent Sutherland <ksuther@ithinksw.com>
7  *   Responsibility : Kent Sutherland <ksuther@ithinksw.com>
8  *
9  *  Copyright (c) 2003 iThink Software.
10  *  All Rights Reserved
11  *
12  */
13
14 #import "NetworkController.h"
15 #import "MainController.h"
16 #import "netinet/in.h"
17 #import "arpa/inet.h"
18 #import <ITFoundation/ITDebug.h>
19 #import <ITFoundation/ITFoundation.h>
20 #import <ITMTRemote/ITMTRemote.h>
21
22 static NetworkController *sharedController;
23
24 @implementation NetworkController
25
26 + (NetworkController *)sharedController
27 {
28     return sharedController;
29 }
30
31 - (id)init
32 {
33     if ( (self = [super init]) ) {
34         sharedController = self;
35         browser = [[NSNetServiceBrowser alloc] init];
36         [browser setDelegate:self];
37     }
38     return self;
39 }
40
41 - (void)dealloc
42 {
43     [self disconnect];
44     if (serverOn) {
45         [serverConnection invalidate];
46         [serverConnection release];
47     }
48     [clientProxy release];
49     [remoteServices release];
50     [browser release];
51     [service stop];
52     [service release];
53     [super dealloc];
54 }
55
56 - (void)startRemoteServerSearch
57 {
58     [browser searchForServicesOfType:@"_mttp._tcp." inDomain:@""];
59     [remoteServices release];
60     remoteServices = [[NSMutableArray alloc] init];
61 }
62
63 - (void)stopRemoteServerSearch
64 {
65     [browser stop];
66 }
67
68 - (void)setServerStatus:(BOOL)status
69 {
70     if (!serverOn && status) {
71         NSString *name = [[NSUserDefaults standardUserDefaults] stringForKey:@"sharedPlayerName"];
72         //Turn on
73         NS_DURING
74             serverPort = [[NSSocketPort alloc] initWithTCPPort:SERVER_PORT];
75             serverConnection = [[NSConnection alloc] initWithReceivePort:serverPort
76                                                      sendPort:serverPort];
77             [serverConnection setRootObject:[[MainController sharedController] currentRemote]];
78             [serverConnection registerName:@"ITMTPlayerHost"];
79             [serverConnection setDelegate:self];
80         NS_HANDLER
81             ITDebugLog(@"Error starting server!");
82         NS_ENDHANDLER
83         ITDebugLog(@"Started server.");
84         if (!name) {
85             name = @"MenuTunes Shared Player";
86         }
87         service = [[NSNetService alloc] initWithDomain:@""
88                                         type:@"_mttp._tcp."
89                                         name:name
90                                         port:SERVER_PORT];
91         [service publish];
92         serverOn = YES;
93     } else if (serverOn && !status && [serverConnection isValid]) {
94         //Turn off
95         [service stop];
96         [serverConnection registerName:nil];
97         [serverPort invalidate];
98         [serverConnection invalidate];
99         [serverConnection release];
100         ITDebugLog(@"Stopped server.");
101         serverOn = NO;
102     }
103 }
104
105 - (BOOL)connectToHost:(NSString *)host
106 {
107     ITDebugLog(@"Connecting to host: %@", host);
108     NS_DURING
109         clientPort = [[NSSocketPort alloc] initRemoteWithTCPPort:SERVER_PORT
110                                            host:host];
111         clientConnection = [[NSConnection connectionWithReceivePort:nil sendPort:clientPort] retain];
112         clientProxy = [[clientConnection rootProxy] retain];
113     NS_HANDLER
114         ITDebugLog(@"Connection to host failed: %@", host);
115         return NO;
116     NS_ENDHANDLER
117     [clientConnection setReplyTimeout:5];
118     ITDebugLog(@"Connected to host: %@", host);
119     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(disconnect) name:NSConnectionDidDieNotification object:clientConnection];
120     connectedToServer = YES;
121     return YES;
122 }
123
124 - (BOOL)disconnect
125 {
126     ITDebugLog(@"Disconnecting from host.");
127     connectedToServer = NO;
128     [[NSNotificationCenter defaultCenter] removeObserver:self];
129     [clientProxy release];
130     [clientConnection invalidate];
131     [clientConnection release];
132     return YES;
133 }
134
135 - (BOOL)isServerOn
136 {
137     return serverOn;
138 }
139
140 - (BOOL)isClientConnected
141 {
142     return clientConnected;
143 }
144
145 - (BOOL)isConnectedToServer
146 {
147     return connectedToServer;
148 }
149
150 - (ITMTRemote *)sharedRemote
151 {
152     return (ITMTRemote *)clientProxy;
153 }
154
155 - (NSArray *)remoteServices
156 {
157     return remoteServices;
158 }
159
160 - (void)netServiceBrowser:(NSNetServiceBrowser *)aNetServiceBrowser didFindService:(NSNetService *)aNetService moreComing:(BOOL)moreComing
161 {
162     [aNetService setDelegate:self];
163     [aNetService resolve];
164     ITDebugLog(@"Found service named %@.", [aNetService name]);
165     if (!moreComing) {
166         [[NSNotificationCenter defaultCenter] postNotificationName:@"ITMTFoundNetService" object:nil];
167     }
168 }
169
170 - (void)netServiceDidResolveAddress:(NSNetService *)sender
171 {
172     [remoteServices addObject:[NSDictionary dictionaryWithObjectsAndKeys:[sender name], @"name",
173                                                                          [NSString stringWithCString:inet_ntoa((*(struct sockaddr_in*)[[[sender addresses] objectAtIndex:0] bytes]).sin_addr)], @"ip",
174                                                                          nil, nil]];
175     ITDebugLog(@"Resolved service named %@.", [sender name]);
176     NSLog(@"found!");
177     [[NSNotificationCenter defaultCenter] postNotificationName:@"ITMTFoundNetService" object:nil];
178 }
179
180 - (void)netServiceWillResolve:(NSNetService *)sender
181 {
182     ITDebugLog(@"Resolving service named %@.", [sender name]);
183 }
184
185 - (void)netService:(NSNetService *)sender didNotResolve:(NSDictionary *)errorDict
186 {
187     ITDebugLog(@"Error resolving service %@.", errorDict);
188 }
189
190 @end