UIDevice-Reachability.m 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. //
  2. // UIDevice-Reachability.m
  3. // CpcProject
  4. //
  5. // Created by by Jason Lee on 13. 6. 28..
  6. // Copyright (c) jasondevelop. All rights reserved.
  7. //
  8. @import SystemConfiguration;
  9. #include <arpa/inet.h>
  10. #include <netdb.h>
  11. #include <net/if.h>
  12. #include <ifaddrs.h>
  13. #import <dlfcn.h>
  14. #import "UIDevice-Reachability.h"
  15. //#import "URLControllr.h"
  16. @implementation UIDevice (Reachability)
  17. SCNetworkConnectionFlags connectionFlags;
  18. SCNetworkReachabilityRef reachability;
  19. #pragma mark Checking Connections
  20. + (void) pingReachabilityInternal{
  21. if (!reachability){
  22. BOOL ignoresAdHocWiFi = NO;
  23. struct sockaddr_in ipAddress;
  24. bzero(&ipAddress, sizeof(ipAddress));
  25. ipAddress.sin_len = sizeof(ipAddress);
  26. ipAddress.sin_family = AF_INET;
  27. ipAddress.sin_addr.s_addr = htonl(ignoresAdHocWiFi ? INADDR_ANY : IN_LINKLOCALNETNUM);
  28. reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (struct sockaddr *)&ipAddress);
  29. CFRetain(reachability);
  30. }
  31. // Recover reachability flags
  32. BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(reachability, &connectionFlags);
  33. if (!didRetrieveFlags) {
  34. // printf("Error. Could not recover network reachability flags\n");
  35. }
  36. }
  37. + (NSString *) localWiFiIPAddress{
  38. BOOL success;
  39. struct ifaddrs * addrs;
  40. const struct ifaddrs * cursor;
  41. NSString *temp = nil;
  42. success = getifaddrs(&addrs) == 0;
  43. if (success) {
  44. cursor = addrs;
  45. while (cursor != NULL) {
  46. // the second test keeps from picking up the loopback address
  47. if (cursor->ifa_addr->sa_family ==
  48. AF_INET && (cursor->ifa_flags & IFF_LOOPBACK) == 0)
  49. {
  50. NSString *name = [NSString stringWithUTF8String:cursor->ifa_name];
  51. if ([name isEqualToString:@"en0"]){ // Wi-Fi adapter
  52. //return [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)cursor->ifa_addr)->sin_addr)];
  53. temp = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)cursor->ifa_addr)->sin_addr)];
  54. break;
  55. }
  56. }
  57. cursor = cursor->ifa_next;
  58. }
  59. freeifaddrs(addrs);
  60. }
  61. return temp;
  62. }
  63. + (BOOL) networkAvailable{
  64. [self pingReachabilityInternal];
  65. BOOL isReachable = ((connectionFlags & kSCNetworkFlagsReachable) != 0);
  66. BOOL needsConnection = ((connectionFlags & kSCNetworkFlagsConnectionRequired) != 0);
  67. return (isReachable && !needsConnection) ? YES : NO;
  68. }
  69. + (BOOL) activeWWAN{
  70. if (![self networkAvailable]) return NO;
  71. return ((connectionFlags & kSCNetworkReachabilityFlagsIsWWAN) != 0);
  72. }
  73. + (BOOL) activeWLAN{
  74. return ([UIDevice localWiFiIPAddress] != nil);
  75. }
  76. #pragma mark Monitoring reachability
  77. static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkConnectionFlags flags, void* info){
  78. // NSAutoreleasePool *pool = [NSAutoreleasePool new];
  79. [(__bridge id)info performSelector:@selector(reachabilityChanged)];
  80. // [pool release];
  81. }
  82. + (BOOL) scheduleReachabilityWatcher: (id) watcher{
  83. if (![watcher conformsToProtocol:@protocol(ReachabilityWatcher)]) {
  84. NSLog(@"Watcher must conform to ReachabilityWatcher protocol. Cannot continue.");
  85. return NO;
  86. }
  87. [self pingReachabilityInternal];
  88. SCNetworkReachabilityContext context = {0, (__bridge void *)(watcher), NULL, NULL, NULL};
  89. if(SCNetworkReachabilitySetCallback(reachability, ReachabilityCallback, &context)) {
  90. if(!SCNetworkReachabilityScheduleWithRunLoop(reachability, CFRunLoopGetCurrent(), kCFRunLoopCommonModes)) {
  91. NSLog(@"Error: Could not schedule reachability");
  92. SCNetworkReachabilitySetCallback(reachability, NULL, NULL);
  93. return NO;
  94. }
  95. } else {
  96. NSLog(@"Error: Could not set reachability callback");
  97. return NO;
  98. }
  99. return YES;
  100. }
  101. + (void) unscheduleReachabilityWatcher{
  102. SCNetworkReachabilitySetCallback(reachability, NULL, NULL);
  103. if (SCNetworkReachabilityUnscheduleFromRunLoop(reachability, CFRunLoopGetCurrent(), kCFRunLoopCommonModes))
  104. NSLog(@"Unscheduled reachability");
  105. else
  106. NSLog(@"Error: Could not unschedule reachability");
  107. CFRelease(reachability);
  108. reachability = nil;
  109. }
  110. #ifdef SUPPORTS_UNDOCUMENTED_API
  111. #define SBSERVPATH "/System/Library/PrivateFrameworks/SpringBoardServices.framework/SpringBoardServices"
  112. #define UIKITPATH "/System/Library/Framework/UIKit.framework/UIKit"
  113. // Don't use this code in real life, boys and girls. It is not App Store friendly.
  114. // It is, however, really nice for testing callbacks
  115. + (void) setAPMode: (BOOL) yorn{
  116. mach_port_t *thePort;
  117. void *uikit = dlopen(UIKITPATH, RTLD_LAZY);
  118. int (*SBSSpringBoardServerPort)() = dlsym(uikit, "SBSSpringBoardServerPort");
  119. thePort = (mach_port_t *)SBSSpringBoardServerPort();
  120. dlclose(uikit);
  121. // Link to SBSetAirplaneModeEnabled
  122. void *sbserv = dlopen(SBSERVPATH, RTLD_LAZY);
  123. int (*setAPMode)(mach_port_t* port, BOOL yorn) = dlsym(sbserv, "SBSetAirplaneModeEnabled");
  124. setAPMode(thePort, yorn);
  125. dlclose(sbserv);
  126. }
  127. #endif
  128. @end