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 |