Statistics
| Branch: | Tag: | Revision:

root / Classes / Reachability.m @ 9fee07a6

History | View | Annotate | Download (23.5 kB)

1 700184fb Miltiadis Vasilakis
/*
2 700184fb Miltiadis Vasilakis
 
3 700184fb Miltiadis Vasilakis
 File: Reachability.m
4 700184fb Miltiadis Vasilakis
 Abstract: Basic demonstration of how to use the SystemConfiguration Reachablity APIs.
5 700184fb Miltiadis Vasilakis
 
6 700184fb Miltiadis Vasilakis
 Version: 2.0.4ddg
7 700184fb Miltiadis Vasilakis
 */
8 700184fb Miltiadis Vasilakis
9 700184fb Miltiadis Vasilakis
/*
10 700184fb Miltiadis Vasilakis
 Significant additions made by Andrew W. Donoho, August 11, 2009.
11 700184fb Miltiadis Vasilakis
 This is a derived work of Apple's Reachability v2.0 class.
12 700184fb Miltiadis Vasilakis
 
13 700184fb Miltiadis Vasilakis
 The below license is the new BSD license with the OSI recommended personalizations.
14 700184fb Miltiadis Vasilakis
 <http://www.opensource.org/licenses/bsd-license.php>
15 700184fb Miltiadis Vasilakis
16 700184fb Miltiadis Vasilakis
 Extensions Copyright (C) 2009 Donoho Design Group, LLC. All Rights Reserved.
17 700184fb Miltiadis Vasilakis
 
18 700184fb Miltiadis Vasilakis
 Redistribution and use in source and binary forms, with or without
19 700184fb Miltiadis Vasilakis
 modification, are permitted provided that the following conditions are
20 700184fb Miltiadis Vasilakis
 met:
21 700184fb Miltiadis Vasilakis
 
22 700184fb Miltiadis Vasilakis
 * Redistributions of source code must retain the above copyright notice,
23 700184fb Miltiadis Vasilakis
 this list of conditions and the following disclaimer.
24 700184fb Miltiadis Vasilakis
 
25 700184fb Miltiadis Vasilakis
 * Redistributions in binary form must reproduce the above copyright
26 700184fb Miltiadis Vasilakis
 notice, this list of conditions and the following disclaimer in the
27 700184fb Miltiadis Vasilakis
 documentation and/or other materials provided with the distribution.
28 700184fb Miltiadis Vasilakis
 
29 700184fb Miltiadis Vasilakis
 * Neither the name of Andrew W. Donoho nor Donoho Design Group, L.L.C.
30 700184fb Miltiadis Vasilakis
 may be used to endorse or promote products derived from this software
31 700184fb Miltiadis Vasilakis
 without specific prior written permission.
32 700184fb Miltiadis Vasilakis
 
33 700184fb Miltiadis Vasilakis
 THIS SOFTWARE IS PROVIDED BY DONOHO DESIGN GROUP, L.L.C. "AS IS" AND ANY
34 700184fb Miltiadis Vasilakis
 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
35 700184fb Miltiadis Vasilakis
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
36 700184fb Miltiadis Vasilakis
 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
37 700184fb Miltiadis Vasilakis
 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
38 700184fb Miltiadis Vasilakis
 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
39 700184fb Miltiadis Vasilakis
 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
40 700184fb Miltiadis Vasilakis
 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
41 700184fb Miltiadis Vasilakis
 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
42 700184fb Miltiadis Vasilakis
 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
43 700184fb Miltiadis Vasilakis
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44 700184fb Miltiadis Vasilakis
 
45 700184fb Miltiadis Vasilakis
 */
46 700184fb Miltiadis Vasilakis
47 700184fb Miltiadis Vasilakis
48 700184fb Miltiadis Vasilakis
/*
49 700184fb Miltiadis Vasilakis
 
50 700184fb Miltiadis Vasilakis
 Apple's Original License on Reachability v2.0
51 700184fb Miltiadis Vasilakis
 
52 700184fb Miltiadis Vasilakis
 Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple Inc.
53 700184fb Miltiadis Vasilakis
 ("Apple") in consideration of your agreement to the following terms, and your
54 700184fb Miltiadis Vasilakis
 use, installation, modification or redistribution of this Apple software
55 700184fb Miltiadis Vasilakis
 constitutes acceptance of these terms.  If you do not agree with these terms,
56 700184fb Miltiadis Vasilakis
 please do not use, install, modify or redistribute this Apple software.
57 700184fb Miltiadis Vasilakis
 
58 700184fb Miltiadis Vasilakis
 In consideration of your agreement to abide by the following terms, and subject
59 700184fb Miltiadis Vasilakis
 to these terms, Apple grants you a personal, non-exclusive license, under
60 700184fb Miltiadis Vasilakis
 Apple's copyrights in this original Apple software (the "Apple Software"), to
61 700184fb Miltiadis Vasilakis
 use, reproduce, modify and redistribute the Apple Software, with or without
62 700184fb Miltiadis Vasilakis
 modifications, in source and/or binary forms; provided that if you redistribute
63 700184fb Miltiadis Vasilakis
 the Apple Software in its entirety and without modifications, you must retain
64 700184fb Miltiadis Vasilakis
 this notice and the following text and disclaimers in all such redistributions
65 700184fb Miltiadis Vasilakis
 of the Apple Software.
66 700184fb Miltiadis Vasilakis
67 700184fb Miltiadis Vasilakis
 Neither the name, trademarks, service marks or logos of Apple Inc. may be used
68 700184fb Miltiadis Vasilakis
 to endorse or promote products derived from the Apple Software without specific
69 700184fb Miltiadis Vasilakis
 prior written permission from Apple.  Except as expressly stated in this notice,
70 700184fb Miltiadis Vasilakis
 no other rights or licenses, express or implied, are granted by Apple herein,
71 700184fb Miltiadis Vasilakis
 including but not limited to any patent rights that may be infringed by your
72 700184fb Miltiadis Vasilakis
 derivative works or by other works in which the Apple Software may be
73 700184fb Miltiadis Vasilakis
 incorporated.
74 700184fb Miltiadis Vasilakis
 
75 700184fb Miltiadis Vasilakis
 The Apple Software is provided by Apple on an "AS IS" basis.  APPLE MAKES NO
76 700184fb Miltiadis Vasilakis
 WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
77 700184fb Miltiadis Vasilakis
 WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
78 700184fb Miltiadis Vasilakis
 PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
79 700184fb Miltiadis Vasilakis
 COMBINATION WITH YOUR PRODUCTS.
80 700184fb Miltiadis Vasilakis
 
81 700184fb Miltiadis Vasilakis
 IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
82 700184fb Miltiadis Vasilakis
 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
83 700184fb Miltiadis Vasilakis
 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
84 700184fb Miltiadis Vasilakis
 ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR
85 700184fb Miltiadis Vasilakis
 DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF
86 700184fb Miltiadis Vasilakis
 CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
87 700184fb Miltiadis Vasilakis
 APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88 700184fb Miltiadis Vasilakis
 
89 700184fb Miltiadis Vasilakis
 Copyright (C) 2009 Apple Inc. All Rights Reserved.
90 700184fb Miltiadis Vasilakis
 
91 700184fb Miltiadis Vasilakis
*/
92 700184fb Miltiadis Vasilakis
93 700184fb Miltiadis Vasilakis
/*
94 700184fb Miltiadis Vasilakis
 Each reachability object now has a copy of the key used to store it in a dictionary.
95 700184fb Miltiadis Vasilakis
 This allows each observer to quickly determine if the event is important to them.
96 700184fb Miltiadis Vasilakis
*/
97 700184fb Miltiadis Vasilakis
98 700184fb Miltiadis Vasilakis
#import <sys/socket.h>
99 700184fb Miltiadis Vasilakis
#import <netinet/in.h>
100 700184fb Miltiadis Vasilakis
#import <netinet6/in6.h>
101 700184fb Miltiadis Vasilakis
#import <arpa/inet.h>
102 700184fb Miltiadis Vasilakis
#import <ifaddrs.h>
103 700184fb Miltiadis Vasilakis
#import <netdb.h>
104 700184fb Miltiadis Vasilakis
105 700184fb Miltiadis Vasilakis
#import <CoreFoundation/CoreFoundation.h>
106 700184fb Miltiadis Vasilakis
107 700184fb Miltiadis Vasilakis
#import "Reachability.h"
108 700184fb Miltiadis Vasilakis
109 700184fb Miltiadis Vasilakis
NSString *const kInternetConnection  = @"InternetConnection";
110 700184fb Miltiadis Vasilakis
NSString *const kLocalWiFiConnection = @"LocalWiFiConnection";
111 700184fb Miltiadis Vasilakis
NSString *const kReachabilityChangedNotification = @"NetworkReachabilityChangedNotification";
112 700184fb Miltiadis Vasilakis
113 700184fb Miltiadis Vasilakis
#define CLASS_DEBUG 1 // Turn on logReachabilityFlags. Must also have a project wide defined DEBUG.
114 700184fb Miltiadis Vasilakis
115 700184fb Miltiadis Vasilakis
#if (defined DEBUG && defined CLASS_DEBUG)
116 700184fb Miltiadis Vasilakis
#define logReachabilityFlags(flags) (logReachabilityFlags_(__PRETTY_FUNCTION__, __LINE__, flags))
117 700184fb Miltiadis Vasilakis
118 700184fb Miltiadis Vasilakis
static NSString *reachabilityFlags_(SCNetworkReachabilityFlags flags) {
119 700184fb Miltiadis Vasilakis
	
120 700184fb Miltiadis Vasilakis
#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 30000) // Apple advises you to use the magic number instead of a symbol.
121 700184fb Miltiadis Vasilakis
    return [NSString stringWithFormat:@"Reachability Flags: %c%c %c%c%c%c%c%c%c",
122 700184fb Miltiadis Vasilakis
			(flags & kSCNetworkReachabilityFlagsIsWWAN)               ? 'W' : '-',
123 700184fb Miltiadis Vasilakis
			(flags & kSCNetworkReachabilityFlagsReachable)            ? 'R' : '-',
124 700184fb Miltiadis Vasilakis
			
125 700184fb Miltiadis Vasilakis
			(flags & kSCNetworkReachabilityFlagsConnectionRequired)   ? 'c' : '-',
126 700184fb Miltiadis Vasilakis
			(flags & kSCNetworkReachabilityFlagsTransientConnection)  ? 't' : '-',
127 700184fb Miltiadis Vasilakis
			(flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-',
128 700184fb Miltiadis Vasilakis
			(flags & kSCNetworkReachabilityFlagsConnectionOnTraffic)  ? 'C' : '-',
129 700184fb Miltiadis Vasilakis
			(flags & kSCNetworkReachabilityFlagsConnectionOnDemand)   ? 'D' : '-',
130 700184fb Miltiadis Vasilakis
			(flags & kSCNetworkReachabilityFlagsIsLocalAddress)       ? 'l' : '-',
131 700184fb Miltiadis Vasilakis
			(flags & kSCNetworkReachabilityFlagsIsDirect)             ? 'd' : '-'];
132 700184fb Miltiadis Vasilakis
#else
133 700184fb Miltiadis Vasilakis
	// Compile out the v3.0 features for v2.2.1 deployment.
134 700184fb Miltiadis Vasilakis
    return [NSString stringWithFormat:@"Reachability Flags: %c%c %c%c%c%c%c%c",
135 700184fb Miltiadis Vasilakis
			(flags & kSCNetworkReachabilityFlagsIsWWAN)               ? 'W' : '-',
136 700184fb Miltiadis Vasilakis
			(flags & kSCNetworkReachabilityFlagsReachable)            ? 'R' : '-',
137 700184fb Miltiadis Vasilakis
			
138 700184fb Miltiadis Vasilakis
			(flags & kSCNetworkReachabilityFlagsConnectionRequired)   ? 'c' : '-',
139 700184fb Miltiadis Vasilakis
			(flags & kSCNetworkReachabilityFlagsTransientConnection)  ? 't' : '-',
140 700184fb Miltiadis Vasilakis
			(flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-',
141 700184fb Miltiadis Vasilakis
			// v3 kSCNetworkReachabilityFlagsConnectionOnTraffic == v2 kSCNetworkReachabilityFlagsConnectionAutomatic
142 700184fb Miltiadis Vasilakis
			(flags & kSCNetworkReachabilityFlagsConnectionAutomatic)  ? 'C' : '-',
143 700184fb Miltiadis Vasilakis
			// (flags & kSCNetworkReachabilityFlagsConnectionOnDemand)   ? 'D' : '-', // No v2 equivalent.
144 700184fb Miltiadis Vasilakis
			(flags & kSCNetworkReachabilityFlagsIsLocalAddress)       ? 'l' : '-',
145 700184fb Miltiadis Vasilakis
			(flags & kSCNetworkReachabilityFlagsIsDirect)             ? 'd' : '-'];
146 700184fb Miltiadis Vasilakis
#endif
147 700184fb Miltiadis Vasilakis
	
148 700184fb Miltiadis Vasilakis
} // reachabilityFlags_()
149 700184fb Miltiadis Vasilakis
150 700184fb Miltiadis Vasilakis
static void logReachabilityFlags_(const char *name, int line, SCNetworkReachabilityFlags flags) {
151 700184fb Miltiadis Vasilakis
	
152 700184fb Miltiadis Vasilakis
    NSLog(@"%s (%d) \n\t%@", name, line, reachabilityFlags_(flags));
153 700184fb Miltiadis Vasilakis
	
154 700184fb Miltiadis Vasilakis
} // logReachabilityFlags_()
155 700184fb Miltiadis Vasilakis
156 700184fb Miltiadis Vasilakis
#define logNetworkStatus(status) (logNetworkStatus_(__PRETTY_FUNCTION__, __LINE__, status))
157 700184fb Miltiadis Vasilakis
158 700184fb Miltiadis Vasilakis
static void logNetworkStatus_(const char *name, int line, NetworkStatus status) {
159 700184fb Miltiadis Vasilakis
	
160 700184fb Miltiadis Vasilakis
	NSString *statusString = nil;
161 700184fb Miltiadis Vasilakis
	
162 700184fb Miltiadis Vasilakis
	switch (status) {
163 700184fb Miltiadis Vasilakis
		case kNotReachable:
164 700184fb Miltiadis Vasilakis
			statusString = [NSString stringWithString: @"Not Reachable"];
165 700184fb Miltiadis Vasilakis
			break;
166 700184fb Miltiadis Vasilakis
		case kReachableViaWWAN:
167 700184fb Miltiadis Vasilakis
			statusString = [NSString stringWithString: @"Reachable via WWAN"];
168 700184fb Miltiadis Vasilakis
			break;
169 700184fb Miltiadis Vasilakis
		case kReachableViaWiFi:
170 700184fb Miltiadis Vasilakis
			statusString = [NSString stringWithString: @"Reachable via WiFi"];
171 700184fb Miltiadis Vasilakis
			break;
172 700184fb Miltiadis Vasilakis
	}
173 700184fb Miltiadis Vasilakis
	
174 700184fb Miltiadis Vasilakis
	NSLog(@"%s (%d) \n\tNetwork Status: %@", name, line, statusString);
175 700184fb Miltiadis Vasilakis
	
176 700184fb Miltiadis Vasilakis
} // logNetworkStatus_()
177 700184fb Miltiadis Vasilakis
178 700184fb Miltiadis Vasilakis
#else
179 700184fb Miltiadis Vasilakis
#define logReachabilityFlags(flags)
180 700184fb Miltiadis Vasilakis
#define logNetworkStatus(status)
181 700184fb Miltiadis Vasilakis
#endif
182 700184fb Miltiadis Vasilakis
183 700184fb Miltiadis Vasilakis
@interface Reachability (private)
184 700184fb Miltiadis Vasilakis
185 700184fb Miltiadis Vasilakis
- (NetworkStatus) networkStatusForFlags: (SCNetworkReachabilityFlags) flags;
186 700184fb Miltiadis Vasilakis
187 700184fb Miltiadis Vasilakis
@end
188 700184fb Miltiadis Vasilakis
189 700184fb Miltiadis Vasilakis
@implementation Reachability
190 700184fb Miltiadis Vasilakis
191 700184fb Miltiadis Vasilakis
@synthesize key = key_;
192 700184fb Miltiadis Vasilakis
193 700184fb Miltiadis Vasilakis
// Preclude direct access to ivars.
194 700184fb Miltiadis Vasilakis
+ (BOOL) accessInstanceVariablesDirectly {
195 700184fb Miltiadis Vasilakis
	
196 700184fb Miltiadis Vasilakis
	return NO;
197 700184fb Miltiadis Vasilakis
198 700184fb Miltiadis Vasilakis
} // accessInstanceVariablesDirectly
199 700184fb Miltiadis Vasilakis
200 700184fb Miltiadis Vasilakis
201 700184fb Miltiadis Vasilakis
- (void) dealloc {
202 700184fb Miltiadis Vasilakis
	
203 700184fb Miltiadis Vasilakis
	[self stopNotifier];
204 700184fb Miltiadis Vasilakis
	if(reachabilityRef) {
205 700184fb Miltiadis Vasilakis
		
206 700184fb Miltiadis Vasilakis
		CFRelease(reachabilityRef); reachabilityRef = NULL;
207 700184fb Miltiadis Vasilakis
		
208 700184fb Miltiadis Vasilakis
	}
209 700184fb Miltiadis Vasilakis
	
210 700184fb Miltiadis Vasilakis
	self.key = nil;
211 700184fb Miltiadis Vasilakis
	
212 700184fb Miltiadis Vasilakis
	[super dealloc];
213 700184fb Miltiadis Vasilakis
	
214 700184fb Miltiadis Vasilakis
} // dealloc
215 700184fb Miltiadis Vasilakis
216 700184fb Miltiadis Vasilakis
217 700184fb Miltiadis Vasilakis
- (Reachability *) initWithReachabilityRef: (SCNetworkReachabilityRef) ref 
218 700184fb Miltiadis Vasilakis
{
219 700184fb Miltiadis Vasilakis
    self = [super init];
220 700184fb Miltiadis Vasilakis
	if (self != nil) 
221 700184fb Miltiadis Vasilakis
    {
222 700184fb Miltiadis Vasilakis
		reachabilityRef = ref;
223 700184fb Miltiadis Vasilakis
	}
224 700184fb Miltiadis Vasilakis
	
225 700184fb Miltiadis Vasilakis
	return self;
226 700184fb Miltiadis Vasilakis
	
227 700184fb Miltiadis Vasilakis
} // initWithReachabilityRef:
228 700184fb Miltiadis Vasilakis
229 700184fb Miltiadis Vasilakis
230 700184fb Miltiadis Vasilakis
#if (defined DEBUG && defined CLASS_DEBUG)
231 700184fb Miltiadis Vasilakis
- (NSString *) description {
232 700184fb Miltiadis Vasilakis
	
233 700184fb Miltiadis Vasilakis
	NSAssert(reachabilityRef, @"-description called with NULL reachabilityRef");
234 700184fb Miltiadis Vasilakis
	
235 700184fb Miltiadis Vasilakis
	SCNetworkReachabilityFlags flags = 0;
236 700184fb Miltiadis Vasilakis
	
237 700184fb Miltiadis Vasilakis
	SCNetworkReachabilityGetFlags(reachabilityRef, &flags);
238 700184fb Miltiadis Vasilakis
	
239 700184fb Miltiadis Vasilakis
	return [NSString stringWithFormat: @"%@\n\t%@", self.key, reachabilityFlags_(flags)];
240 700184fb Miltiadis Vasilakis
	
241 700184fb Miltiadis Vasilakis
} // description
242 700184fb Miltiadis Vasilakis
#endif
243 700184fb Miltiadis Vasilakis
244 700184fb Miltiadis Vasilakis
245 700184fb Miltiadis Vasilakis
#pragma mark -
246 700184fb Miltiadis Vasilakis
#pragma mark Notification Management Methods
247 700184fb Miltiadis Vasilakis
248 700184fb Miltiadis Vasilakis
249 700184fb Miltiadis Vasilakis
//Start listening for reachability notifications on the current run loop
250 700184fb Miltiadis Vasilakis
static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info) {
251 700184fb Miltiadis Vasilakis
252 700184fb Miltiadis Vasilakis
	#pragma unused (target, flags)
253 700184fb Miltiadis Vasilakis
	NSCAssert(info, @"info was NULL in ReachabilityCallback");
254 700184fb Miltiadis Vasilakis
	NSCAssert([(NSObject*) info isKindOfClass: [Reachability class]], @"info was the wrong class in ReachabilityCallback");
255 700184fb Miltiadis Vasilakis
	
256 700184fb Miltiadis Vasilakis
	//We're on the main RunLoop, so an NSAutoreleasePool is not necessary, but is added defensively
257 700184fb Miltiadis Vasilakis
	// in case someone uses the Reachablity object in a different thread.
258 700184fb Miltiadis Vasilakis
	NSAutoreleasePool* pool = [NSAutoreleasePool new];
259 700184fb Miltiadis Vasilakis
	
260 700184fb Miltiadis Vasilakis
	// Post a notification to notify the client that the network reachability changed.
261 700184fb Miltiadis Vasilakis
	[[NSNotificationCenter defaultCenter] postNotificationName: kReachabilityChangedNotification 
262 700184fb Miltiadis Vasilakis
														object: (Reachability *) info];
263 700184fb Miltiadis Vasilakis
	
264 700184fb Miltiadis Vasilakis
	[pool release];
265 700184fb Miltiadis Vasilakis
266 700184fb Miltiadis Vasilakis
} // ReachabilityCallback()
267 700184fb Miltiadis Vasilakis
268 700184fb Miltiadis Vasilakis
269 700184fb Miltiadis Vasilakis
- (BOOL) startNotifier {
270 700184fb Miltiadis Vasilakis
	
271 700184fb Miltiadis Vasilakis
	SCNetworkReachabilityContext	context = {0, self, NULL, NULL, NULL};
272 700184fb Miltiadis Vasilakis
	
273 700184fb Miltiadis Vasilakis
	if(SCNetworkReachabilitySetCallback(reachabilityRef, ReachabilityCallback, &context)) {
274 700184fb Miltiadis Vasilakis
		
275 700184fb Miltiadis Vasilakis
		if(SCNetworkReachabilityScheduleWithRunLoop(reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode)) {
276 700184fb Miltiadis Vasilakis
277 700184fb Miltiadis Vasilakis
			return YES;
278 700184fb Miltiadis Vasilakis
			
279 700184fb Miltiadis Vasilakis
		}
280 700184fb Miltiadis Vasilakis
		
281 700184fb Miltiadis Vasilakis
	}
282 700184fb Miltiadis Vasilakis
	
283 700184fb Miltiadis Vasilakis
	return NO;
284 700184fb Miltiadis Vasilakis
285 700184fb Miltiadis Vasilakis
} // startNotifier
286 700184fb Miltiadis Vasilakis
287 700184fb Miltiadis Vasilakis
288 700184fb Miltiadis Vasilakis
- (void) stopNotifier {
289 700184fb Miltiadis Vasilakis
	
290 700184fb Miltiadis Vasilakis
	if(reachabilityRef) {
291 700184fb Miltiadis Vasilakis
		
292 700184fb Miltiadis Vasilakis
		SCNetworkReachabilityUnscheduleFromRunLoop(reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
293 700184fb Miltiadis Vasilakis
294 700184fb Miltiadis Vasilakis
	}
295 700184fb Miltiadis Vasilakis
296 700184fb Miltiadis Vasilakis
} // stopNotifier
297 700184fb Miltiadis Vasilakis
298 700184fb Miltiadis Vasilakis
299 700184fb Miltiadis Vasilakis
- (BOOL) isEqual: (Reachability *) r {
300 700184fb Miltiadis Vasilakis
	
301 700184fb Miltiadis Vasilakis
	return [r.key isEqualToString: self.key];
302 700184fb Miltiadis Vasilakis
	
303 700184fb Miltiadis Vasilakis
} // isEqual:
304 700184fb Miltiadis Vasilakis
305 700184fb Miltiadis Vasilakis
306 700184fb Miltiadis Vasilakis
#pragma mark -
307 700184fb Miltiadis Vasilakis
#pragma mark Reachability Allocation Methods
308 700184fb Miltiadis Vasilakis
309 700184fb Miltiadis Vasilakis
310 700184fb Miltiadis Vasilakis
+ (Reachability *) reachabilityWithHostName: (NSString *) hostName {
311 700184fb Miltiadis Vasilakis
	
312 700184fb Miltiadis Vasilakis
	SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithName(NULL, [hostName UTF8String]);
313 700184fb Miltiadis Vasilakis
	
314 700184fb Miltiadis Vasilakis
	if (ref) {
315 700184fb Miltiadis Vasilakis
		
316 700184fb Miltiadis Vasilakis
		Reachability *r = [[[self alloc] initWithReachabilityRef: ref] autorelease];
317 700184fb Miltiadis Vasilakis
		
318 700184fb Miltiadis Vasilakis
		r.key = hostName;
319 700184fb Miltiadis Vasilakis
320 700184fb Miltiadis Vasilakis
		return r;
321 700184fb Miltiadis Vasilakis
		
322 700184fb Miltiadis Vasilakis
	}
323 700184fb Miltiadis Vasilakis
	
324 700184fb Miltiadis Vasilakis
	return nil;
325 700184fb Miltiadis Vasilakis
	
326 700184fb Miltiadis Vasilakis
} // reachabilityWithHostName
327 700184fb Miltiadis Vasilakis
328 700184fb Miltiadis Vasilakis
329 700184fb Miltiadis Vasilakis
+ (NSString *) makeAddressKey: (in_addr_t) addr {
330 700184fb Miltiadis Vasilakis
	// addr is assumed to be in network byte order.
331 700184fb Miltiadis Vasilakis
	
332 700184fb Miltiadis Vasilakis
	static const int       highShift    = 24;
333 700184fb Miltiadis Vasilakis
	static const int       highMidShift = 16;
334 700184fb Miltiadis Vasilakis
	static const int       lowMidShift  =  8;
335 700184fb Miltiadis Vasilakis
	static const in_addr_t mask         = 0x000000ff;
336 700184fb Miltiadis Vasilakis
	
337 700184fb Miltiadis Vasilakis
	addr = ntohl(addr);
338 700184fb Miltiadis Vasilakis
	
339 700184fb Miltiadis Vasilakis
	return [NSString stringWithFormat: @"%d.%d.%d.%d", 
340 700184fb Miltiadis Vasilakis
			(addr >> highShift)    & mask, 
341 700184fb Miltiadis Vasilakis
			(addr >> highMidShift) & mask, 
342 700184fb Miltiadis Vasilakis
			(addr >> lowMidShift)  & mask, 
343 700184fb Miltiadis Vasilakis
			 addr                  & mask];
344 700184fb Miltiadis Vasilakis
	
345 700184fb Miltiadis Vasilakis
} // makeAddressKey:
346 700184fb Miltiadis Vasilakis
347 700184fb Miltiadis Vasilakis
348 700184fb Miltiadis Vasilakis
+ (Reachability *) reachabilityWithAddress: (const struct sockaddr_in *) hostAddress {
349 700184fb Miltiadis Vasilakis
	
350 700184fb Miltiadis Vasilakis
	SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)hostAddress);
351 700184fb Miltiadis Vasilakis
352 700184fb Miltiadis Vasilakis
	if (ref) {
353 700184fb Miltiadis Vasilakis
		
354 700184fb Miltiadis Vasilakis
		Reachability *r = [[[self alloc] initWithReachabilityRef: ref] autorelease];
355 700184fb Miltiadis Vasilakis
		
356 700184fb Miltiadis Vasilakis
		r.key = [self makeAddressKey: hostAddress->sin_addr.s_addr];
357 700184fb Miltiadis Vasilakis
		
358 700184fb Miltiadis Vasilakis
		return r;
359 700184fb Miltiadis Vasilakis
		
360 700184fb Miltiadis Vasilakis
	}
361 700184fb Miltiadis Vasilakis
	
362 700184fb Miltiadis Vasilakis
	return nil;
363 700184fb Miltiadis Vasilakis
364 700184fb Miltiadis Vasilakis
} // reachabilityWithAddress
365 700184fb Miltiadis Vasilakis
366 700184fb Miltiadis Vasilakis
367 700184fb Miltiadis Vasilakis
+ (Reachability *) reachabilityForInternetConnection {
368 700184fb Miltiadis Vasilakis
	
369 700184fb Miltiadis Vasilakis
	struct sockaddr_in zeroAddress;
370 700184fb Miltiadis Vasilakis
	bzero(&zeroAddress, sizeof(zeroAddress));
371 700184fb Miltiadis Vasilakis
	zeroAddress.sin_len = sizeof(zeroAddress);
372 700184fb Miltiadis Vasilakis
	zeroAddress.sin_family = AF_INET;
373 700184fb Miltiadis Vasilakis
374 700184fb Miltiadis Vasilakis
	Reachability *r = [self reachabilityWithAddress: &zeroAddress];
375 700184fb Miltiadis Vasilakis
376 700184fb Miltiadis Vasilakis
	r.key = kInternetConnection;
377 700184fb Miltiadis Vasilakis
	
378 700184fb Miltiadis Vasilakis
	return r;
379 700184fb Miltiadis Vasilakis
380 700184fb Miltiadis Vasilakis
} // reachabilityForInternetConnection
381 700184fb Miltiadis Vasilakis
382 700184fb Miltiadis Vasilakis
383 700184fb Miltiadis Vasilakis
+ (Reachability *) reachabilityForLocalWiFi {
384 700184fb Miltiadis Vasilakis
	
385 700184fb Miltiadis Vasilakis
	struct sockaddr_in localWifiAddress;
386 700184fb Miltiadis Vasilakis
	bzero(&localWifiAddress, sizeof(localWifiAddress));
387 700184fb Miltiadis Vasilakis
	localWifiAddress.sin_len = sizeof(localWifiAddress);
388 700184fb Miltiadis Vasilakis
	localWifiAddress.sin_family = AF_INET;
389 700184fb Miltiadis Vasilakis
	// IN_LINKLOCALNETNUM is defined in <netinet/in.h> as 169.254.0.0
390 700184fb Miltiadis Vasilakis
	localWifiAddress.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM);
391 700184fb Miltiadis Vasilakis
392 700184fb Miltiadis Vasilakis
	Reachability *r = [self reachabilityWithAddress: &localWifiAddress];
393 700184fb Miltiadis Vasilakis
394 700184fb Miltiadis Vasilakis
	r.key = kLocalWiFiConnection;
395 700184fb Miltiadis Vasilakis
396 700184fb Miltiadis Vasilakis
	return r;
397 700184fb Miltiadis Vasilakis
398 700184fb Miltiadis Vasilakis
} // reachabilityForLocalWiFi
399 700184fb Miltiadis Vasilakis
400 700184fb Miltiadis Vasilakis
401 700184fb Miltiadis Vasilakis
#pragma mark -
402 700184fb Miltiadis Vasilakis
#pragma mark Network Flag Handling Methods
403 700184fb Miltiadis Vasilakis
404 700184fb Miltiadis Vasilakis
405 700184fb Miltiadis Vasilakis
#if USE_DDG_EXTENSIONS
406 700184fb Miltiadis Vasilakis
//
407 700184fb Miltiadis Vasilakis
// iPhone condition codes as reported by a 3GS running iPhone OS v3.0.
408 700184fb Miltiadis Vasilakis
// Airplane Mode turned on:  Reachability Flag Status: -- -------
409 700184fb Miltiadis Vasilakis
// WWAN Active:              Reachability Flag Status: WR -t-----
410 700184fb Miltiadis Vasilakis
// WWAN Connection required: Reachability Flag Status: WR ct-----
411 700184fb Miltiadis Vasilakis
//         WiFi turned on:   Reachability Flag Status: -R ------- Reachable.
412 700184fb Miltiadis Vasilakis
// Local   WiFi turned on:   Reachability Flag Status: -R xxxxxxd Reachable.
413 700184fb Miltiadis Vasilakis
//         WiFi turned on:   Reachability Flag Status: -R ct----- Connection down. (Non-intuitive, empirically determined answer.)
414 700184fb Miltiadis Vasilakis
const SCNetworkReachabilityFlags kConnectionDown =  kSCNetworkReachabilityFlagsConnectionRequired | 
415 700184fb Miltiadis Vasilakis
												    kSCNetworkReachabilityFlagsTransientConnection;
416 700184fb Miltiadis Vasilakis
//         WiFi turned on:   Reachability Flag Status: -R ct-i--- Reachable but it will require user intervention (e.g. enter a WiFi password).
417 700184fb Miltiadis Vasilakis
//         WiFi turned on:   Reachability Flag Status: -R -t----- Reachable via VPN.
418 700184fb Miltiadis Vasilakis
//
419 700184fb Miltiadis Vasilakis
// In the below method, an 'x' in the flag status means I don't care about its value.
420 700184fb Miltiadis Vasilakis
//
421 700184fb Miltiadis Vasilakis
// This method differs from Apple's by testing explicitly for empirically observed values.
422 700184fb Miltiadis Vasilakis
// This gives me more confidence in it's correct behavior. Apple's code covers more cases 
423 700184fb Miltiadis Vasilakis
// than mine. My code covers the cases that occur.
424 700184fb Miltiadis Vasilakis
//
425 700184fb Miltiadis Vasilakis
- (NetworkStatus) networkStatusForFlags: (SCNetworkReachabilityFlags) flags {
426 700184fb Miltiadis Vasilakis
	
427 700184fb Miltiadis Vasilakis
	if (flags & kSCNetworkReachabilityFlagsReachable) {
428 700184fb Miltiadis Vasilakis
		
429 700184fb Miltiadis Vasilakis
		// Local WiFi -- Test derived from Apple's code: -localWiFiStatusForFlags:.
430 700184fb Miltiadis Vasilakis
		if (self.key == kLocalWiFiConnection) {
431 700184fb Miltiadis Vasilakis
432 700184fb Miltiadis Vasilakis
			// Reachability Flag Status: xR xxxxxxd Reachable.
433 700184fb Miltiadis Vasilakis
			return (flags & kSCNetworkReachabilityFlagsIsDirect) ? kReachableViaWiFi : kNotReachable;
434 700184fb Miltiadis Vasilakis
435 700184fb Miltiadis Vasilakis
		}
436 700184fb Miltiadis Vasilakis
		
437 700184fb Miltiadis Vasilakis
		// Observed WWAN Values:
438 700184fb Miltiadis Vasilakis
		// WWAN Active:              Reachability Flag Status: WR -t-----
439 700184fb Miltiadis Vasilakis
		// WWAN Connection required: Reachability Flag Status: WR ct-----
440 700184fb Miltiadis Vasilakis
		//
441 700184fb Miltiadis Vasilakis
		// Test Value: Reachability Flag Status: WR xxxxxxx
442 700184fb Miltiadis Vasilakis
		if (flags & kSCNetworkReachabilityFlagsIsWWAN) { return kReachableViaWWAN; }
443 700184fb Miltiadis Vasilakis
		
444 700184fb Miltiadis Vasilakis
		// Clear moot bits.
445 700184fb Miltiadis Vasilakis
		flags &= ~kSCNetworkReachabilityFlagsReachable;
446 700184fb Miltiadis Vasilakis
		flags &= ~kSCNetworkReachabilityFlagsIsDirect;
447 700184fb Miltiadis Vasilakis
		flags &= ~kSCNetworkReachabilityFlagsIsLocalAddress; // kInternetConnection is local.
448 700184fb Miltiadis Vasilakis
		
449 700184fb Miltiadis Vasilakis
		// Reachability Flag Status: -R ct---xx Connection down.
450 700184fb Miltiadis Vasilakis
		if (flags == kConnectionDown) { return kNotReachable; }
451 700184fb Miltiadis Vasilakis
		
452 700184fb Miltiadis Vasilakis
		// Reachability Flag Status: -R -t---xx Reachable. WiFi + VPN(is up) (Thank you Ling Wang)
453 700184fb Miltiadis Vasilakis
		if (flags & kSCNetworkReachabilityFlagsTransientConnection)  { return kReachableViaWiFi; }
454 700184fb Miltiadis Vasilakis
			
455 700184fb Miltiadis Vasilakis
		// Reachability Flag Status: -R -----xx Reachable.
456 700184fb Miltiadis Vasilakis
		if (flags == 0) { return kReachableViaWiFi; }
457 700184fb Miltiadis Vasilakis
		
458 700184fb Miltiadis Vasilakis
		// Apple's code tests for dynamic connection types here. I don't. 
459 700184fb Miltiadis Vasilakis
		// If a connection is required, regardless of whether it is on demand or not, it is a WiFi connection.
460 700184fb Miltiadis Vasilakis
		// If you care whether a connection needs to be brought up,   use -isConnectionRequired.
461 700184fb Miltiadis Vasilakis
		// If you care about whether user intervention is necessary,  use -isInterventionRequired.
462 700184fb Miltiadis Vasilakis
		// If you care about dynamically establishing the connection, use -isConnectionIsOnDemand.
463 700184fb Miltiadis Vasilakis
464 700184fb Miltiadis Vasilakis
		// Reachability Flag Status: -R cxxxxxx Reachable.
465 700184fb Miltiadis Vasilakis
		if (flags & kSCNetworkReachabilityFlagsConnectionRequired) { return kReachableViaWiFi; }
466 700184fb Miltiadis Vasilakis
		
467 700184fb Miltiadis Vasilakis
		// Required by the compiler. Should never get here. Default to not connected.
468 700184fb Miltiadis Vasilakis
#if (defined DEBUG && defined CLASS_DEBUG)
469 700184fb Miltiadis Vasilakis
		NSAssert1(NO, @"Uncaught reachability test. Flags: %@", reachabilityFlags_(flags));
470 700184fb Miltiadis Vasilakis
#endif
471 700184fb Miltiadis Vasilakis
		return kNotReachable;
472 700184fb Miltiadis Vasilakis
473 700184fb Miltiadis Vasilakis
		}
474 700184fb Miltiadis Vasilakis
	
475 700184fb Miltiadis Vasilakis
	// Reachability Flag Status: x- xxxxxxx
476 700184fb Miltiadis Vasilakis
	return kNotReachable;
477 700184fb Miltiadis Vasilakis
	
478 700184fb Miltiadis Vasilakis
} // networkStatusForFlags:
479 700184fb Miltiadis Vasilakis
480 700184fb Miltiadis Vasilakis
481 700184fb Miltiadis Vasilakis
- (NetworkStatus) currentReachabilityStatus {
482 700184fb Miltiadis Vasilakis
	
483 700184fb Miltiadis Vasilakis
	NSAssert(reachabilityRef, @"currentReachabilityStatus called with NULL reachabilityRef");
484 700184fb Miltiadis Vasilakis
	
485 700184fb Miltiadis Vasilakis
	SCNetworkReachabilityFlags flags = 0;
486 700184fb Miltiadis Vasilakis
	NetworkStatus status = kNotReachable;
487 700184fb Miltiadis Vasilakis
	
488 700184fb Miltiadis Vasilakis
	if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
489 700184fb Miltiadis Vasilakis
		
490 700184fb Miltiadis Vasilakis
//		logReachabilityFlags(flags);
491 700184fb Miltiadis Vasilakis
		
492 700184fb Miltiadis Vasilakis
		status = [self networkStatusForFlags: flags];
493 700184fb Miltiadis Vasilakis
		
494 700184fb Miltiadis Vasilakis
		return status;
495 700184fb Miltiadis Vasilakis
		
496 700184fb Miltiadis Vasilakis
	}
497 700184fb Miltiadis Vasilakis
	
498 700184fb Miltiadis Vasilakis
	return kNotReachable;
499 700184fb Miltiadis Vasilakis
	
500 700184fb Miltiadis Vasilakis
} // currentReachabilityStatus
501 700184fb Miltiadis Vasilakis
502 700184fb Miltiadis Vasilakis
503 700184fb Miltiadis Vasilakis
- (BOOL) isReachable {
504 700184fb Miltiadis Vasilakis
	
505 700184fb Miltiadis Vasilakis
	NSAssert(reachabilityRef, @"isReachable called with NULL reachabilityRef");
506 700184fb Miltiadis Vasilakis
	
507 700184fb Miltiadis Vasilakis
	SCNetworkReachabilityFlags flags = 0;
508 700184fb Miltiadis Vasilakis
	NetworkStatus status = kNotReachable;
509 700184fb Miltiadis Vasilakis
	
510 700184fb Miltiadis Vasilakis
	if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
511 700184fb Miltiadis Vasilakis
		
512 700184fb Miltiadis Vasilakis
//		logReachabilityFlags(flags);
513 700184fb Miltiadis Vasilakis
514 700184fb Miltiadis Vasilakis
		status = [self networkStatusForFlags: flags];
515 700184fb Miltiadis Vasilakis
516 700184fb Miltiadis Vasilakis
//		logNetworkStatus(status);
517 700184fb Miltiadis Vasilakis
		
518 700184fb Miltiadis Vasilakis
		return (kNotReachable != status);
519 700184fb Miltiadis Vasilakis
		
520 700184fb Miltiadis Vasilakis
	}
521 700184fb Miltiadis Vasilakis
	
522 700184fb Miltiadis Vasilakis
	return NO;
523 700184fb Miltiadis Vasilakis
	
524 700184fb Miltiadis Vasilakis
} // isReachable
525 700184fb Miltiadis Vasilakis
526 700184fb Miltiadis Vasilakis
527 700184fb Miltiadis Vasilakis
- (BOOL) isConnectionRequired {
528 700184fb Miltiadis Vasilakis
	
529 700184fb Miltiadis Vasilakis
	NSAssert(reachabilityRef, @"isConnectionRequired called with NULL reachabilityRef");
530 700184fb Miltiadis Vasilakis
	
531 700184fb Miltiadis Vasilakis
	SCNetworkReachabilityFlags flags;
532 700184fb Miltiadis Vasilakis
	
533 700184fb Miltiadis Vasilakis
	if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
534 700184fb Miltiadis Vasilakis
		
535 700184fb Miltiadis Vasilakis
		logReachabilityFlags(flags);
536 700184fb Miltiadis Vasilakis
		
537 700184fb Miltiadis Vasilakis
		return (flags & kSCNetworkReachabilityFlagsConnectionRequired);
538 700184fb Miltiadis Vasilakis
539 700184fb Miltiadis Vasilakis
	}
540 700184fb Miltiadis Vasilakis
	
541 700184fb Miltiadis Vasilakis
	return NO;
542 700184fb Miltiadis Vasilakis
	
543 700184fb Miltiadis Vasilakis
} // isConnectionRequired
544 700184fb Miltiadis Vasilakis
545 700184fb Miltiadis Vasilakis
546 700184fb Miltiadis Vasilakis
- (BOOL) connectionRequired {
547 700184fb Miltiadis Vasilakis
	
548 700184fb Miltiadis Vasilakis
	return [self isConnectionRequired];
549 700184fb Miltiadis Vasilakis
	
550 700184fb Miltiadis Vasilakis
} // connectionRequired
551 700184fb Miltiadis Vasilakis
#endif
552 700184fb Miltiadis Vasilakis
553 700184fb Miltiadis Vasilakis
554 700184fb Miltiadis Vasilakis
#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 30000)
555 700184fb Miltiadis Vasilakis
static const SCNetworkReachabilityFlags kOnDemandConnection = kSCNetworkReachabilityFlagsConnectionOnTraffic | 
556 700184fb Miltiadis Vasilakis
                                                              kSCNetworkReachabilityFlagsConnectionOnDemand;
557 700184fb Miltiadis Vasilakis
#else
558 700184fb Miltiadis Vasilakis
static const SCNetworkReachabilityFlags kOnDemandConnection = kSCNetworkReachabilityFlagsConnectionAutomatic;
559 700184fb Miltiadis Vasilakis
#endif
560 700184fb Miltiadis Vasilakis
561 700184fb Miltiadis Vasilakis
- (BOOL) isConnectionOnDemand {
562 700184fb Miltiadis Vasilakis
	
563 700184fb Miltiadis Vasilakis
	NSAssert(reachabilityRef, @"isConnectionIsOnDemand called with NULL reachabilityRef");
564 700184fb Miltiadis Vasilakis
	
565 700184fb Miltiadis Vasilakis
	SCNetworkReachabilityFlags flags;
566 700184fb Miltiadis Vasilakis
	
567 700184fb Miltiadis Vasilakis
	if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
568 700184fb Miltiadis Vasilakis
		
569 700184fb Miltiadis Vasilakis
		logReachabilityFlags(flags);
570 700184fb Miltiadis Vasilakis
		
571 700184fb Miltiadis Vasilakis
		return ((flags & kSCNetworkReachabilityFlagsConnectionRequired) &&
572 700184fb Miltiadis Vasilakis
				(flags & kOnDemandConnection));
573 700184fb Miltiadis Vasilakis
		
574 700184fb Miltiadis Vasilakis
	}
575 700184fb Miltiadis Vasilakis
	
576 700184fb Miltiadis Vasilakis
	return NO;
577 700184fb Miltiadis Vasilakis
	
578 700184fb Miltiadis Vasilakis
} // isConnectionOnDemand
579 700184fb Miltiadis Vasilakis
580 700184fb Miltiadis Vasilakis
581 700184fb Miltiadis Vasilakis
- (BOOL) isInterventionRequired {
582 700184fb Miltiadis Vasilakis
	
583 700184fb Miltiadis Vasilakis
	NSAssert(reachabilityRef, @"isInterventionRequired called with NULL reachabilityRef");
584 700184fb Miltiadis Vasilakis
	
585 700184fb Miltiadis Vasilakis
	SCNetworkReachabilityFlags flags;
586 700184fb Miltiadis Vasilakis
	
587 700184fb Miltiadis Vasilakis
	if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
588 700184fb Miltiadis Vasilakis
		
589 700184fb Miltiadis Vasilakis
		logReachabilityFlags(flags);
590 700184fb Miltiadis Vasilakis
		
591 700184fb Miltiadis Vasilakis
		return ((flags & kSCNetworkReachabilityFlagsConnectionRequired) &&
592 700184fb Miltiadis Vasilakis
				(flags & kSCNetworkReachabilityFlagsInterventionRequired));
593 700184fb Miltiadis Vasilakis
		
594 700184fb Miltiadis Vasilakis
	}
595 700184fb Miltiadis Vasilakis
	
596 700184fb Miltiadis Vasilakis
	return NO;
597 700184fb Miltiadis Vasilakis
	
598 700184fb Miltiadis Vasilakis
} // isInterventionRequired
599 700184fb Miltiadis Vasilakis
600 700184fb Miltiadis Vasilakis
601 700184fb Miltiadis Vasilakis
- (BOOL) isReachableViaWWAN {
602 700184fb Miltiadis Vasilakis
	
603 700184fb Miltiadis Vasilakis
	NSAssert(reachabilityRef, @"isReachableViaWWAN called with NULL reachabilityRef");
604 700184fb Miltiadis Vasilakis
	
605 700184fb Miltiadis Vasilakis
	SCNetworkReachabilityFlags flags = 0;
606 700184fb Miltiadis Vasilakis
	NetworkStatus status = kNotReachable;
607 700184fb Miltiadis Vasilakis
	
608 700184fb Miltiadis Vasilakis
	if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
609 700184fb Miltiadis Vasilakis
		
610 700184fb Miltiadis Vasilakis
		logReachabilityFlags(flags);
611 700184fb Miltiadis Vasilakis
		
612 700184fb Miltiadis Vasilakis
		status = [self networkStatusForFlags: flags];
613 700184fb Miltiadis Vasilakis
		
614 700184fb Miltiadis Vasilakis
		return  (kReachableViaWWAN == status);
615 700184fb Miltiadis Vasilakis
			
616 700184fb Miltiadis Vasilakis
	}
617 700184fb Miltiadis Vasilakis
	
618 700184fb Miltiadis Vasilakis
	return NO;
619 700184fb Miltiadis Vasilakis
	
620 700184fb Miltiadis Vasilakis
} // isReachableViaWWAN
621 700184fb Miltiadis Vasilakis
622 700184fb Miltiadis Vasilakis
623 700184fb Miltiadis Vasilakis
- (BOOL) isReachableViaWiFi {
624 700184fb Miltiadis Vasilakis
	
625 700184fb Miltiadis Vasilakis
	NSAssert(reachabilityRef, @"isReachableViaWiFi called with NULL reachabilityRef");
626 700184fb Miltiadis Vasilakis
	
627 700184fb Miltiadis Vasilakis
	SCNetworkReachabilityFlags flags = 0;
628 700184fb Miltiadis Vasilakis
	NetworkStatus status = kNotReachable;
629 700184fb Miltiadis Vasilakis
	
630 700184fb Miltiadis Vasilakis
	if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
631 700184fb Miltiadis Vasilakis
		
632 700184fb Miltiadis Vasilakis
		logReachabilityFlags(flags);
633 700184fb Miltiadis Vasilakis
		
634 700184fb Miltiadis Vasilakis
		status = [self networkStatusForFlags: flags];
635 700184fb Miltiadis Vasilakis
		
636 700184fb Miltiadis Vasilakis
		return  (kReachableViaWiFi == status);
637 700184fb Miltiadis Vasilakis
		
638 700184fb Miltiadis Vasilakis
	}
639 700184fb Miltiadis Vasilakis
	
640 700184fb Miltiadis Vasilakis
	return NO;
641 700184fb Miltiadis Vasilakis
	
642 700184fb Miltiadis Vasilakis
} // isReachableViaWiFi
643 700184fb Miltiadis Vasilakis
644 700184fb Miltiadis Vasilakis
645 700184fb Miltiadis Vasilakis
- (SCNetworkReachabilityFlags) reachabilityFlags {
646 700184fb Miltiadis Vasilakis
	
647 700184fb Miltiadis Vasilakis
	NSAssert(reachabilityRef, @"reachabilityFlags called with NULL reachabilityRef");
648 700184fb Miltiadis Vasilakis
	
649 700184fb Miltiadis Vasilakis
	SCNetworkReachabilityFlags flags = 0;
650 700184fb Miltiadis Vasilakis
	
651 700184fb Miltiadis Vasilakis
	if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
652 700184fb Miltiadis Vasilakis
		
653 700184fb Miltiadis Vasilakis
		logReachabilityFlags(flags);
654 700184fb Miltiadis Vasilakis
		
655 700184fb Miltiadis Vasilakis
		return flags;
656 700184fb Miltiadis Vasilakis
		
657 700184fb Miltiadis Vasilakis
	}
658 700184fb Miltiadis Vasilakis
	
659 700184fb Miltiadis Vasilakis
	return 0;
660 700184fb Miltiadis Vasilakis
	
661 700184fb Miltiadis Vasilakis
} // reachabilityFlags
662 700184fb Miltiadis Vasilakis
663 700184fb Miltiadis Vasilakis
664 700184fb Miltiadis Vasilakis
#pragma mark -
665 700184fb Miltiadis Vasilakis
#pragma mark Apple's Network Flag Handling Methods
666 700184fb Miltiadis Vasilakis
667 700184fb Miltiadis Vasilakis
668 700184fb Miltiadis Vasilakis
#if !USE_DDG_EXTENSIONS
669 700184fb Miltiadis Vasilakis
/*
670 700184fb Miltiadis Vasilakis
 *
671 700184fb Miltiadis Vasilakis
 *  Apple's Network Status testing code.
672 700184fb Miltiadis Vasilakis
 *  The only changes that have been made are to use the new logReachabilityFlags macro and
673 700184fb Miltiadis Vasilakis
 *  test for local WiFi via the key instead of Apple's boolean. Also, Apple's code was for v3.0 only
674 700184fb Miltiadis Vasilakis
 *  iPhone OS. v2.2.1 and earlier conditional compiling is turned on. Hence, to mirror Apple's behavior,
675 700184fb Miltiadis Vasilakis
 *  set your Base SDK to v3.0 or higher.
676 700184fb Miltiadis Vasilakis
 *
677 700184fb Miltiadis Vasilakis
 */
678 700184fb Miltiadis Vasilakis
679 700184fb Miltiadis Vasilakis
- (NetworkStatus) localWiFiStatusForFlags: (SCNetworkReachabilityFlags) flags
680 700184fb Miltiadis Vasilakis
{
681 700184fb Miltiadis Vasilakis
	logReachabilityFlags(flags);
682 700184fb Miltiadis Vasilakis
	
683 700184fb Miltiadis Vasilakis
	BOOL retVal = NotReachable;
684 700184fb Miltiadis Vasilakis
	if((flags & kSCNetworkReachabilityFlagsReachable) && (flags & kSCNetworkReachabilityFlagsIsDirect))
685 700184fb Miltiadis Vasilakis
	{
686 700184fb Miltiadis Vasilakis
		retVal = ReachableViaWiFi;	
687 700184fb Miltiadis Vasilakis
	}
688 700184fb Miltiadis Vasilakis
	return retVal;
689 700184fb Miltiadis Vasilakis
}
690 700184fb Miltiadis Vasilakis
691 700184fb Miltiadis Vasilakis
692 700184fb Miltiadis Vasilakis
- (NetworkStatus) networkStatusForFlags: (SCNetworkReachabilityFlags) flags
693 700184fb Miltiadis Vasilakis
{
694 700184fb Miltiadis Vasilakis
	logReachabilityFlags(flags);
695 700184fb Miltiadis Vasilakis
	if (!(flags & kSCNetworkReachabilityFlagsReachable))
696 700184fb Miltiadis Vasilakis
	{
697 700184fb Miltiadis Vasilakis
		// if target host is not reachable
698 700184fb Miltiadis Vasilakis
		return NotReachable;
699 700184fb Miltiadis Vasilakis
	}
700 700184fb Miltiadis Vasilakis
	
701 700184fb Miltiadis Vasilakis
	BOOL retVal = NotReachable;
702 700184fb Miltiadis Vasilakis
	
703 700184fb Miltiadis Vasilakis
	if (!(flags & kSCNetworkReachabilityFlagsConnectionRequired))
704 700184fb Miltiadis Vasilakis
	{
705 700184fb Miltiadis Vasilakis
		// if target host is reachable and no connection is required
706 700184fb Miltiadis Vasilakis
		//  then we'll assume (for now) that your on Wi-Fi
707 700184fb Miltiadis Vasilakis
		retVal = ReachableViaWiFi;
708 700184fb Miltiadis Vasilakis
	}
709 700184fb Miltiadis Vasilakis
	
710 700184fb Miltiadis Vasilakis
#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 30000) // Apple advises you to use the magic number instead of a symbol.	
711 700184fb Miltiadis Vasilakis
	if ((flags & kSCNetworkReachabilityFlagsConnectionOnDemand) ||
712 700184fb Miltiadis Vasilakis
		(flags & kSCNetworkReachabilityFlagsConnectionOnTraffic))
713 700184fb Miltiadis Vasilakis
#else
714 700184fb Miltiadis Vasilakis
	if (flags & kSCNetworkReachabilityFlagsConnectionAutomatic)
715 700184fb Miltiadis Vasilakis
#endif
716 700184fb Miltiadis Vasilakis
		{
717 700184fb Miltiadis Vasilakis
			// ... and the connection is on-demand (or on-traffic) if the
718 700184fb Miltiadis Vasilakis
			//     calling application is using the CFSocketStream or higher APIs
719 700184fb Miltiadis Vasilakis
			
720 700184fb Miltiadis Vasilakis
			if (!(flags & kSCNetworkReachabilityFlagsInterventionRequired))
721 700184fb Miltiadis Vasilakis
			{
722 700184fb Miltiadis Vasilakis
				// ... and no [user] intervention is needed
723 700184fb Miltiadis Vasilakis
				retVal = ReachableViaWiFi;
724 700184fb Miltiadis Vasilakis
			}
725 700184fb Miltiadis Vasilakis
		}
726 700184fb Miltiadis Vasilakis
	
727 700184fb Miltiadis Vasilakis
	if (flags & kSCNetworkReachabilityFlagsIsWWAN)
728 700184fb Miltiadis Vasilakis
	{
729 700184fb Miltiadis Vasilakis
		// ... but WWAN connections are OK if the calling application
730 700184fb Miltiadis Vasilakis
		//     is using the CFNetwork (CFSocketStream?) APIs.
731 700184fb Miltiadis Vasilakis
		retVal = ReachableViaWWAN;
732 700184fb Miltiadis Vasilakis
	}
733 700184fb Miltiadis Vasilakis
	return retVal;
734 700184fb Miltiadis Vasilakis
}
735 700184fb Miltiadis Vasilakis
736 700184fb Miltiadis Vasilakis
737 700184fb Miltiadis Vasilakis
- (NetworkStatus) currentReachabilityStatus
738 700184fb Miltiadis Vasilakis
{
739 700184fb Miltiadis Vasilakis
	NSAssert(reachabilityRef, @"currentReachabilityStatus called with NULL reachabilityRef");
740 700184fb Miltiadis Vasilakis
	
741 700184fb Miltiadis Vasilakis
	NetworkStatus retVal = NotReachable;
742 700184fb Miltiadis Vasilakis
	SCNetworkReachabilityFlags flags;
743 700184fb Miltiadis Vasilakis
	if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
744 700184fb Miltiadis Vasilakis
	{
745 700184fb Miltiadis Vasilakis
		if(self.key == kLocalWiFiConnection)
746 700184fb Miltiadis Vasilakis
		{
747 700184fb Miltiadis Vasilakis
			retVal = [self localWiFiStatusForFlags: flags];
748 700184fb Miltiadis Vasilakis
		}
749 700184fb Miltiadis Vasilakis
		else
750 700184fb Miltiadis Vasilakis
		{
751 700184fb Miltiadis Vasilakis
			retVal = [self networkStatusForFlags: flags];
752 700184fb Miltiadis Vasilakis
		}
753 700184fb Miltiadis Vasilakis
	}
754 700184fb Miltiadis Vasilakis
	return retVal;
755 700184fb Miltiadis Vasilakis
}
756 700184fb Miltiadis Vasilakis
757 700184fb Miltiadis Vasilakis
758 700184fb Miltiadis Vasilakis
- (BOOL) isReachable {
759 700184fb Miltiadis Vasilakis
	
760 700184fb Miltiadis Vasilakis
	NSAssert(reachabilityRef, @"isReachable called with NULL reachabilityRef");
761 700184fb Miltiadis Vasilakis
	
762 700184fb Miltiadis Vasilakis
	SCNetworkReachabilityFlags flags = 0;
763 700184fb Miltiadis Vasilakis
	NetworkStatus status = kNotReachable;
764 700184fb Miltiadis Vasilakis
	
765 700184fb Miltiadis Vasilakis
	if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
766 700184fb Miltiadis Vasilakis
		
767 700184fb Miltiadis Vasilakis
		logReachabilityFlags(flags);
768 700184fb Miltiadis Vasilakis
		
769 700184fb Miltiadis Vasilakis
		if(self.key == kLocalWiFiConnection) {
770 700184fb Miltiadis Vasilakis
			
771 700184fb Miltiadis Vasilakis
			status = [self localWiFiStatusForFlags: flags];
772 700184fb Miltiadis Vasilakis
			
773 700184fb Miltiadis Vasilakis
		} else {
774 700184fb Miltiadis Vasilakis
			
775 700184fb Miltiadis Vasilakis
			status = [self networkStatusForFlags: flags];
776 700184fb Miltiadis Vasilakis
			
777 700184fb Miltiadis Vasilakis
		}
778 700184fb Miltiadis Vasilakis
		
779 700184fb Miltiadis Vasilakis
		return (kNotReachable != status);
780 700184fb Miltiadis Vasilakis
		
781 700184fb Miltiadis Vasilakis
	}
782 700184fb Miltiadis Vasilakis
	
783 700184fb Miltiadis Vasilakis
	return NO;
784 700184fb Miltiadis Vasilakis
	
785 700184fb Miltiadis Vasilakis
} // isReachable
786 700184fb Miltiadis Vasilakis
787 700184fb Miltiadis Vasilakis
788 700184fb Miltiadis Vasilakis
- (BOOL) isConnectionRequired {
789 700184fb Miltiadis Vasilakis
	
790 700184fb Miltiadis Vasilakis
	return [self connectionRequired];
791 700184fb Miltiadis Vasilakis
	
792 700184fb Miltiadis Vasilakis
} // isConnectionRequired
793 700184fb Miltiadis Vasilakis
794 700184fb Miltiadis Vasilakis
795 700184fb Miltiadis Vasilakis
- (BOOL) connectionRequired {
796 700184fb Miltiadis Vasilakis
	
797 700184fb Miltiadis Vasilakis
	NSAssert(reachabilityRef, @"connectionRequired called with NULL reachabilityRef");
798 700184fb Miltiadis Vasilakis
	
799 700184fb Miltiadis Vasilakis
	SCNetworkReachabilityFlags flags;
800 700184fb Miltiadis Vasilakis
	
801 700184fb Miltiadis Vasilakis
	if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
802 700184fb Miltiadis Vasilakis
		
803 700184fb Miltiadis Vasilakis
		logReachabilityFlags(flags);
804 700184fb Miltiadis Vasilakis
		
805 700184fb Miltiadis Vasilakis
		return (flags & kSCNetworkReachabilityFlagsConnectionRequired);
806 700184fb Miltiadis Vasilakis
		
807 700184fb Miltiadis Vasilakis
	}
808 700184fb Miltiadis Vasilakis
	
809 700184fb Miltiadis Vasilakis
	return NO;
810 700184fb Miltiadis Vasilakis
	
811 700184fb Miltiadis Vasilakis
} // connectionRequired
812 700184fb Miltiadis Vasilakis
#endif
813 700184fb Miltiadis Vasilakis
814 700184fb Miltiadis Vasilakis
@end