| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814 |
- /*
-
- File: Reachability.m
- Abstract: Basic demonstration of how to use the SystemConfiguration Reachablity APIs.
-
- Version: 2.0.4ddg
- */
- /*
- Significant additions made by Andrew W. Donoho, August 11, 2009.
- This is a derived work of Apple's Reachability v2.0 class.
-
- The below license is the new BSD license with the OSI recommended personalizations.
- <http://www.opensource.org/licenses/bsd-license.php>
- Extensions Copyright (C) 2009 Donoho Design Group, LLC. All Rights Reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of Andrew W. Donoho nor Donoho Design Group, L.L.C.
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY DONOHO DESIGN GROUP, L.L.C. "AS IS" AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- */
- /*
-
- Apple's Original License on Reachability v2.0
-
- Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc.
- ("Apple") in consideration of your agreement to the following terms, and your
- use, installation, modification or redistribution of this Apple software
- constitutes acceptance of these terms. If you do not agree with these terms,
- please do not use, install, modify or redistribute this Apple software.
-
- In consideration of your agreement to abide by the following terms, and subject
- to these terms, Apple grants you a personal, non-exclusive license, under
- Apple's copyrights in this original Apple software (the "Apple Software"), to
- use, reproduce, modify and redistribute the Apple Software, with or without
- modifications, in source and/or binary forms; provided that if you redistribute
- the Apple Software in its entirety and without modifications, you must retain
- this notice and the following text and disclaimers in all such redistributions
- of the Apple Software.
- Neither the name, trademarks, service marks or logos of Apple Inc. may be used
- to endorse or promote products derived from the Apple Software without specific
- prior written permission from Apple. Except as expressly stated in this notice,
- no other rights or licenses, express or implied, are granted by Apple herein,
- including but not limited to any patent rights that may be infringed by your
- derivative works or by other works in which the Apple Software may be
- incorporated.
-
- The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
- WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
- WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
- COMBINATION WITH YOUR PRODUCTS.
-
- IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR
- DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF
- CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
- APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- Copyright (C) 2009 Apple Inc. All Rights Reserved.
-
- */
- /*
- Each reachability object now has a copy of the key used to store it in a dictionary.
- This allows each observer to quickly determine if the event is important to them.
- */
- #import <sys/socket.h>
- #import <netinet/in.h>
- #import <netinet6/in6.h>
- #import <arpa/inet.h>
- #import <ifaddrs.h>
- #import <netdb.h>
- #import <CoreFoundation/CoreFoundation.h>
- #import "Reachability.h"
- NSString *const kInternetConnection = @"InternetConnection";
- NSString *const kLocalWiFiConnection = @"LocalWiFiConnection";
- NSString *const kReachabilityChangedNotification = @"NetworkReachabilityChangedNotification";
- #define CLASS_DEBUG 1 // Turn on logReachabilityFlags. Must also have a project wide defined DEBUG.
- #if (defined DEBUG && defined CLASS_DEBUG)
- #define logReachabilityFlags(flags) (logReachabilityFlags_(__PRETTY_FUNCTION__, __LINE__, flags))
- static NSString *reachabilityFlags_(SCNetworkReachabilityFlags flags) {
-
- #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 30000) // Apple advises you to use the magic number instead of a symbol.
- return [NSString stringWithFormat:@"Reachability Flags: %c%c %c%c%c%c%c%c%c",
- (flags & kSCNetworkReachabilityFlagsIsWWAN) ? 'W' : '-',
- (flags & kSCNetworkReachabilityFlagsReachable) ? 'R' : '-',
-
- (flags & kSCNetworkReachabilityFlagsConnectionRequired) ? 'c' : '-',
- (flags & kSCNetworkReachabilityFlagsTransientConnection) ? 't' : '-',
- (flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-',
- (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) ? 'C' : '-',
- (flags & kSCNetworkReachabilityFlagsConnectionOnDemand) ? 'D' : '-',
- (flags & kSCNetworkReachabilityFlagsIsLocalAddress) ? 'l' : '-',
- (flags & kSCNetworkReachabilityFlagsIsDirect) ? 'd' : '-'];
- #else
- // Compile out the v3.0 features for v2.2.1 deployment.
- return [NSString stringWithFormat:@"Reachability Flags: %c%c %c%c%c%c%c%c",
- (flags & kSCNetworkReachabilityFlagsIsWWAN) ? 'W' : '-',
- (flags & kSCNetworkReachabilityFlagsReachable) ? 'R' : '-',
-
- (flags & kSCNetworkReachabilityFlagsConnectionRequired) ? 'c' : '-',
- (flags & kSCNetworkReachabilityFlagsTransientConnection) ? 't' : '-',
- (flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-',
- // v3 kSCNetworkReachabilityFlagsConnectionOnTraffic == v2 kSCNetworkReachabilityFlagsConnectionAutomatic
- (flags & kSCNetworkReachabilityFlagsConnectionAutomatic) ? 'C' : '-',
- // (flags & kSCNetworkReachabilityFlagsConnectionOnDemand) ? 'D' : '-', // No v2 equivalent.
- (flags & kSCNetworkReachabilityFlagsIsLocalAddress) ? 'l' : '-',
- (flags & kSCNetworkReachabilityFlagsIsDirect) ? 'd' : '-'];
- #endif
-
- } // reachabilityFlags_()
- static void logReachabilityFlags_(const char *name, int line, SCNetworkReachabilityFlags flags) {
-
- NSLog(@"%s (%d) \n\t%@", name, line, reachabilityFlags_(flags));
-
- } // logReachabilityFlags_()
- #define logNetworkStatus(status) (logNetworkStatus_(__PRETTY_FUNCTION__, __LINE__, status))
- //static void logNetworkStatus_(const char *name, int line, NetworkStatus status) {
- //
- // NSString *statusString = nil;
- //
- // switch (status) {
- // case kNotReachable:
- // statusString = @"Not Reachable";
- // break;
- // case kReachableViaWWAN:
- // statusString = @"Reachable via WWAN";
- // break;
- // case kReachableViaWiFi:
- // statusString = @"Reachable via WiFi";
- // break;
- // }
- //
- // NSLog(@"%s (%d) \n\tNetwork Status: %@", name, line, statusString);
- //
- //} // logNetworkStatus_()
- #else
- #define logReachabilityFlags(flags)
- #define logNetworkStatus(status)
- #endif
- @interface Reachability (private)
- - (NetworkStatus) networkStatusForFlags: (SCNetworkReachabilityFlags) flags;
- @end
- @implementation Reachability
- @synthesize key = key_;
- // Preclude direct access to ivars.
- + (BOOL) accessInstanceVariablesDirectly {
-
- return NO;
- } // accessInstanceVariablesDirectly
- - (void) dealloc {
-
- [self stopNotifier];
- if(reachabilityRef) {
-
- CFRelease(reachabilityRef); reachabilityRef = NULL;
-
- }
-
- self.key = nil;
-
- [super dealloc];
-
- } // dealloc
- - (Reachability *) initWithReachabilityRef: (SCNetworkReachabilityRef) ref
- {
- self = [super init];
- if (self != nil)
- {
- reachabilityRef = ref;
- }
-
- return self;
-
- } // initWithReachabilityRef:
- #if (defined DEBUG && defined CLASS_DEBUG)
- - (NSString *) description {
-
- NSAssert(reachabilityRef, @"-description called with NULL reachabilityRef");
-
- SCNetworkReachabilityFlags flags = 0;
-
- SCNetworkReachabilityGetFlags(reachabilityRef, &flags);
-
- return [NSString stringWithFormat: @"%@\n\t%@", self.key, reachabilityFlags_(flags)];
-
- } // description
- #endif
- #pragma mark -
- #pragma mark Notification Management Methods
- //Start listening for reachability notifications on the current run loop
- static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info) {
- #pragma unused (target, flags)
- NSCAssert(info, @"info was NULL in ReachabilityCallback");
- NSCAssert([(NSObject*) info isKindOfClass: [Reachability class]], @"info was the wrong class in ReachabilityCallback");
-
- //We're on the main RunLoop, so an NSAutoreleasePool is not necessary, but is added defensively
- // in case someone uses the Reachablity object in a different thread.
- NSAutoreleasePool* pool = [NSAutoreleasePool new];
-
- // Post a notification to notify the client that the network reachability changed.
- [[NSNotificationCenter defaultCenter] postNotificationName: kReachabilityChangedNotification
- object: (Reachability *) info];
-
- [pool release];
- } // ReachabilityCallback()
- - (BOOL) startNotifier {
-
- SCNetworkReachabilityContext context = {0, self, NULL, NULL, NULL};
-
- if(SCNetworkReachabilitySetCallback(reachabilityRef, ReachabilityCallback, &context)) {
-
- if(SCNetworkReachabilityScheduleWithRunLoop(reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode)) {
- return YES;
-
- }
-
- }
-
- return NO;
- } // startNotifier
- - (void) stopNotifier {
-
- if(reachabilityRef) {
-
- SCNetworkReachabilityUnscheduleFromRunLoop(reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
- }
- } // stopNotifier
- - (BOOL) isEqual: (Reachability *) r {
-
- return [r.key isEqualToString: self.key];
-
- } // isEqual:
- #pragma mark -
- #pragma mark Reachability Allocation Methods
- + (Reachability *) reachabilityWithHostName: (NSString *) hostName {
-
- SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithName(NULL, [hostName UTF8String]);
-
- if (ref) {
-
- Reachability *r = [[[self alloc] initWithReachabilityRef: ref] autorelease];
-
- r.key = hostName;
- return r;
-
- }
-
- return nil;
-
- } // reachabilityWithHostName
- + (NSString *) makeAddressKey: (in_addr_t) addr {
- // addr is assumed to be in network byte order.
-
- static const int highShift = 24;
- static const int highMidShift = 16;
- static const int lowMidShift = 8;
- static const in_addr_t mask = 0x000000ff;
-
- addr = ntohl(addr);
-
- return [NSString stringWithFormat: @"%d.%d.%d.%d",
- (addr >> highShift) & mask,
- (addr >> highMidShift) & mask,
- (addr >> lowMidShift) & mask,
- addr & mask];
-
- } // makeAddressKey:
- + (Reachability *) reachabilityWithAddress: (const struct sockaddr_in *) hostAddress {
-
- SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)hostAddress);
- if (ref) {
-
- Reachability *r = [[[self alloc] initWithReachabilityRef: ref] autorelease];
-
- r.key = [self makeAddressKey: hostAddress->sin_addr.s_addr];
-
- return r;
-
- }
-
- return nil;
- } // reachabilityWithAddress
- + (Reachability *) reachabilityForInternetConnection {
-
- struct sockaddr_in zeroAddress;
- bzero(&zeroAddress, sizeof(zeroAddress));
- zeroAddress.sin_len = sizeof(zeroAddress);
- zeroAddress.sin_family = AF_INET;
- Reachability *r = [self reachabilityWithAddress: &zeroAddress];
- r.key = kInternetConnection;
-
- return r;
- } // reachabilityForInternetConnection
- + (Reachability *) reachabilityForLocalWiFi {
-
- struct sockaddr_in localWifiAddress;
- bzero(&localWifiAddress, sizeof(localWifiAddress));
- localWifiAddress.sin_len = sizeof(localWifiAddress);
- localWifiAddress.sin_family = AF_INET;
- // IN_LINKLOCALNETNUM is defined in <netinet/in.h> as 169.254.0.0
- localWifiAddress.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM);
- Reachability *r = [self reachabilityWithAddress: &localWifiAddress];
- r.key = kLocalWiFiConnection;
- return r;
- } // reachabilityForLocalWiFi
- #pragma mark -
- #pragma mark Network Flag Handling Methods
- #if USE_DDG_EXTENSIONS
- //
- // iPhone condition codes as reported by a 3GS running iPhone OS v3.0.
- // Airplane Mode turned on: Reachability Flag Status: -- -------
- // WWAN Active: Reachability Flag Status: WR -t-----
- // WWAN Connection required: Reachability Flag Status: WR ct-----
- // WiFi turned on: Reachability Flag Status: -R ------- Reachable.
- // Local WiFi turned on: Reachability Flag Status: -R xxxxxxd Reachable.
- // WiFi turned on: Reachability Flag Status: -R ct----- Connection down. (Non-intuitive, empirically determined answer.)
- const SCNetworkReachabilityFlags kConnectionDown = kSCNetworkReachabilityFlagsConnectionRequired |
- kSCNetworkReachabilityFlagsTransientConnection;
- // WiFi turned on: Reachability Flag Status: -R ct-i--- Reachable but it will require user intervention (e.g. enter a WiFi password).
- // WiFi turned on: Reachability Flag Status: -R -t----- Reachable via VPN.
- //
- // In the below method, an 'x' in the flag status means I don't care about its value.
- //
- // This method differs from Apple's by testing explicitly for empirically observed values.
- // This gives me more confidence in it's correct behavior. Apple's code covers more cases
- // than mine. My code covers the cases that occur.
- //
- - (NetworkStatus) networkStatusForFlags: (SCNetworkReachabilityFlags) flags {
-
- if (flags & kSCNetworkReachabilityFlagsReachable) {
-
- // Local WiFi -- Test derived from Apple's code: -localWiFiStatusForFlags:.
- if (self.key == kLocalWiFiConnection) {
- // Reachability Flag Status: xR xxxxxxd Reachable.
- return (flags & kSCNetworkReachabilityFlagsIsDirect) ? kReachableViaWiFi : kNotReachable;
- }
-
- // Observed WWAN Values:
- // WWAN Active: Reachability Flag Status: WR -t-----
- // WWAN Connection required: Reachability Flag Status: WR ct-----
- //
- // Test Value: Reachability Flag Status: WR xxxxxxx
- if (flags & kSCNetworkReachabilityFlagsIsWWAN) { return kReachableViaWWAN; }
-
- // Clear moot bits.
- flags &= ~kSCNetworkReachabilityFlagsReachable;
- flags &= ~kSCNetworkReachabilityFlagsIsDirect;
- flags &= ~kSCNetworkReachabilityFlagsIsLocalAddress; // kInternetConnection is local.
-
- // Reachability Flag Status: -R ct---xx Connection down.
- if (flags == kConnectionDown) { return kNotReachable; }
-
- // Reachability Flag Status: -R -t---xx Reachable. WiFi + VPN(is up) (Thank you Ling Wang)
- if (flags & kSCNetworkReachabilityFlagsTransientConnection) { return kReachableViaWiFi; }
-
- // Reachability Flag Status: -R -----xx Reachable.
- if (flags == 0) { return kReachableViaWiFi; }
-
- // Apple's code tests for dynamic connection types here. I don't.
- // If a connection is required, regardless of whether it is on demand or not, it is a WiFi connection.
- // If you care whether a connection needs to be brought up, use -isConnectionRequired.
- // If you care about whether user intervention is necessary, use -isInterventionRequired.
- // If you care about dynamically establishing the connection, use -isConnectionIsOnDemand.
- // Reachability Flag Status: -R cxxxxxx Reachable.
- if (flags & kSCNetworkReachabilityFlagsConnectionRequired) { return kReachableViaWiFi; }
-
- // Required by the compiler. Should never get here. Default to not connected.
- #if (defined DEBUG && defined CLASS_DEBUG)
- NSAssert1(NO, @"Uncaught reachability test. Flags: %@", reachabilityFlags_(flags));
- #endif
- return kNotReachable;
- }
-
- // Reachability Flag Status: x- xxxxxxx
- return kNotReachable;
-
- } // networkStatusForFlags:
- - (NetworkStatus) currentReachabilityStatus {
-
- NSAssert(reachabilityRef, @"currentReachabilityStatus called with NULL reachabilityRef");
-
- SCNetworkReachabilityFlags flags = 0;
- NetworkStatus status = kNotReachable;
-
- if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
-
- // logReachabilityFlags(flags);
-
- status = [self networkStatusForFlags: flags];
-
- return status;
-
- }
-
- return kNotReachable;
-
- } // currentReachabilityStatus
- - (BOOL) isReachable {
-
- NSAssert(reachabilityRef, @"isReachable called with NULL reachabilityRef");
-
- SCNetworkReachabilityFlags flags = 0;
- NetworkStatus status = kNotReachable;
-
- if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
-
- // logReachabilityFlags(flags);
- status = [self networkStatusForFlags: flags];
- // logNetworkStatus(status);
-
- return (kNotReachable != status);
-
- }
-
- return NO;
-
- } // isReachable
- - (BOOL) isConnectionRequired {
-
- NSAssert(reachabilityRef, @"isConnectionRequired called with NULL reachabilityRef");
-
- SCNetworkReachabilityFlags flags;
-
- if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
-
- logReachabilityFlags(flags);
-
- return (flags & kSCNetworkReachabilityFlagsConnectionRequired);
- }
-
- return NO;
-
- } // isConnectionRequired
- - (BOOL) connectionRequired {
-
- return [self isConnectionRequired];
-
- } // connectionRequired
- #endif
- #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 30000)
- static const SCNetworkReachabilityFlags kOnDemandConnection = kSCNetworkReachabilityFlagsConnectionOnTraffic |
- kSCNetworkReachabilityFlagsConnectionOnDemand;
- #else
- static const SCNetworkReachabilityFlags kOnDemandConnection = kSCNetworkReachabilityFlagsConnectionAutomatic;
- #endif
- - (BOOL) isConnectionOnDemand {
-
- NSAssert(reachabilityRef, @"isConnectionIsOnDemand called with NULL reachabilityRef");
-
- SCNetworkReachabilityFlags flags;
-
- if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
-
- logReachabilityFlags(flags);
-
- return ((flags & kSCNetworkReachabilityFlagsConnectionRequired) &&
- (flags & kOnDemandConnection));
-
- }
-
- return NO;
-
- } // isConnectionOnDemand
- - (BOOL) isInterventionRequired {
-
- NSAssert(reachabilityRef, @"isInterventionRequired called with NULL reachabilityRef");
-
- SCNetworkReachabilityFlags flags;
-
- if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
-
- logReachabilityFlags(flags);
-
- return ((flags & kSCNetworkReachabilityFlagsConnectionRequired) &&
- (flags & kSCNetworkReachabilityFlagsInterventionRequired));
-
- }
-
- return NO;
-
- } // isInterventionRequired
- - (BOOL) isReachableViaWWAN {
-
- NSAssert(reachabilityRef, @"isReachableViaWWAN called with NULL reachabilityRef");
-
- SCNetworkReachabilityFlags flags = 0;
- NetworkStatus status = kNotReachable;
-
- if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
-
- logReachabilityFlags(flags);
-
- status = [self networkStatusForFlags: flags];
-
- return (kReachableViaWWAN == status);
-
- }
-
- return NO;
-
- } // isReachableViaWWAN
- - (BOOL) isReachableViaWiFi {
-
- NSAssert(reachabilityRef, @"isReachableViaWiFi called with NULL reachabilityRef");
-
- SCNetworkReachabilityFlags flags = 0;
- NetworkStatus status = kNotReachable;
-
- if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
-
- logReachabilityFlags(flags);
-
- status = [self networkStatusForFlags: flags];
-
- return (kReachableViaWiFi == status);
-
- }
-
- return NO;
-
- } // isReachableViaWiFi
- - (SCNetworkReachabilityFlags) reachabilityFlags {
-
- NSAssert(reachabilityRef, @"reachabilityFlags called with NULL reachabilityRef");
-
- SCNetworkReachabilityFlags flags = 0;
-
- if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
-
- logReachabilityFlags(flags);
-
- return flags;
-
- }
-
- return 0;
-
- } // reachabilityFlags
- #pragma mark -
- #pragma mark Apple's Network Flag Handling Methods
- #if !USE_DDG_EXTENSIONS
- /*
- *
- * Apple's Network Status testing code.
- * The only changes that have been made are to use the new logReachabilityFlags macro and
- * test for local WiFi via the key instead of Apple's boolean. Also, Apple's code was for v3.0 only
- * iPhone OS. v2.2.1 and earlier conditional compiling is turned on. Hence, to mirror Apple's behavior,
- * set your Base SDK to v3.0 or higher.
- *
- */
- - (NetworkStatus) localWiFiStatusForFlags: (SCNetworkReachabilityFlags) flags
- {
- logReachabilityFlags(flags);
-
- BOOL retVal = NotReachable;
- if((flags & kSCNetworkReachabilityFlagsReachable) && (flags & kSCNetworkReachabilityFlagsIsDirect))
- {
- retVal = ReachableViaWiFi;
- }
- return retVal;
- }
- - (NetworkStatus) networkStatusForFlags: (SCNetworkReachabilityFlags) flags
- {
- logReachabilityFlags(flags);
- if (!(flags & kSCNetworkReachabilityFlagsReachable))
- {
- // if target host is not reachable
- return NotReachable;
- }
-
- BOOL retVal = NotReachable;
-
- if (!(flags & kSCNetworkReachabilityFlagsConnectionRequired))
- {
- // if target host is reachable and no connection is required
- // then we'll assume (for now) that your on Wi-Fi
- retVal = ReachableViaWiFi;
- }
-
- #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 30000) // Apple advises you to use the magic number instead of a symbol.
- if ((flags & kSCNetworkReachabilityFlagsConnectionOnDemand) ||
- (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic))
- #else
- if (flags & kSCNetworkReachabilityFlagsConnectionAutomatic)
- #endif
- {
- // ... and the connection is on-demand (or on-traffic) if the
- // calling application is using the CFSocketStream or higher APIs
-
- if (!(flags & kSCNetworkReachabilityFlagsInterventionRequired))
- {
- // ... and no [user] intervention is needed
- retVal = ReachableViaWiFi;
- }
- }
-
- if (flags & kSCNetworkReachabilityFlagsIsWWAN)
- {
- // ... but WWAN connections are OK if the calling application
- // is using the CFNetwork (CFSocketStream?) APIs.
- retVal = ReachableViaWWAN;
- }
- return retVal;
- }
- - (NetworkStatus) currentReachabilityStatus
- {
- NSAssert(reachabilityRef, @"currentReachabilityStatus called with NULL reachabilityRef");
-
- NetworkStatus retVal = NotReachable;
- SCNetworkReachabilityFlags flags;
- if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
- {
- if(self.key == kLocalWiFiConnection)
- {
- retVal = [self localWiFiStatusForFlags: flags];
- }
- else
- {
- retVal = [self networkStatusForFlags: flags];
- }
- }
- return retVal;
- }
- - (BOOL) isReachable {
-
- NSAssert(reachabilityRef, @"isReachable called with NULL reachabilityRef");
-
- SCNetworkReachabilityFlags flags = 0;
- NetworkStatus status = kNotReachable;
-
- if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
-
- logReachabilityFlags(flags);
-
- if(self.key == kLocalWiFiConnection) {
-
- status = [self localWiFiStatusForFlags: flags];
-
- } else {
-
- status = [self networkStatusForFlags: flags];
-
- }
-
- return (kNotReachable != status);
-
- }
-
- return NO;
-
- } // isReachable
- - (BOOL) isConnectionRequired {
-
- return [self connectionRequired];
-
- } // isConnectionRequired
- - (BOOL) connectionRequired {
-
- NSAssert(reachabilityRef, @"connectionRequired called with NULL reachabilityRef");
-
- SCNetworkReachabilityFlags flags;
-
- if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
-
- logReachabilityFlags(flags);
-
- return (flags & kSCNetworkReachabilityFlagsConnectionRequired);
-
- }
-
- return NO;
-
- } // connectionRequired
- #endif
- @end
|