Accessing & Using the MobileWiFi.framework
For a personal project of mine, I'm trying to retrieve iPhone WiFi signal strength. I'm fully aware that this in the land of undocumented goodness, so please refrain from the "No Appstore" answers. :)
Anywho, I've been reading up on previous WiFi Network Scanner Apps (WiFi Stumbler), but I'm afraid most (if not all) reflect outdated SDK documentation. Hopefully, this question will also provide some centralized / insightful material with the most recent iPhone SDK 3.1.2.
Here's my incomplete/not-working code:
.h
void *libHandle;
void *airportHandle;
int (*open)(void *);
int (*bind)(void *, NSString *);
int (*close)(void *);
int (*scan)(void *, NSArray **, void *);
.m
libHandle = dlopen("/System/Library/PrivateFrameworks/MobileWiFi.framework/MobileWiFi",RTLD_LAZY);
open = dlsym(libHandle, "Apple80211Open");
bind = dlsym(libHandle, "Apple80211BindToInterface");
close = dlsym(libHandle, "Apple80211Close");
scan = dlsym(libHandle, "Apple80211Scan");
open(&airportHandle);
bind(airportHandle, @"en0");
NSLog(@"Result %@",libHandle);
When executed on the device, it'll produce my ever-so-favorite...
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
I'm thinking the dynamic loading call, isn't loading anything. The directory: /System/Library/PrivateFrameworks/ only lists a Info.plist file with no binaries or aliases.
Probably doing something terribly wrong (wrong directory?)... appreciate any help!
Also, as a follow up. To extract the WiFi information, it might be done by:
GetInfoCopy = dlsym(libHandle, "Apple80211GetInfoCopy");
And my questions are 1) Has anybody had any luck with this? 2) How do you get a header dump like I would using with class-dump on Objective-C libraries (because MobileWifi is in C)?
Solution 1:
For anybody who stumbles upon this question, here's my library to access 802.11 networks. Although Apple claims to deny any applications that use private frameworks, there are several closed-sourced WiFi applications on the AppStore. Use at your own risk.
This library works with iPhone SDK 3.1.2.
- SOLStumbler.h
- SOLStumbler.m
Use:
SOLStumbler *networksManager = [[SOLStumbler alloc] init];
[networksManager scanNetworks];
Result:
An networks NSDictionary of a info NSDictionary.
Use CFShow to explore the returned pointer containing information. Or call the description method for sample output.
Solution 2:
Update as of July 2012 (iOS 5.0)
The code you're trying to use is pretty old. This stuff (e.g. WiFiManager or MobileWiFi) is in a private framework. That means Apple can, and often will, change it or move if from OS version to version.
I ran nm
on the MobileWifi framework, and didn't see any of those function names. So, I think that's why your code fails.
$ pwd /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/PrivateFrameworks/MobileWiFi.framework
$ nm MobileWiFi | grep 80211
$
I suppose it might be necessary to run nm
on the actual device framework, but I didn't waste my time, after looking at this:
Discussion of this framework, and follow-ons.
It looks like you can now find equivalent (?) functions in the IPConfiguration framework. Try this code:
libHandle = dlopen("/System/Library/SystemConfiguration/IPConfiguration.bundle/IPConfiguration", RTLD_LAZY);
I ran it on a jailbroken iOS 5.0.1 phone and it worked (loaded the dylib and found a few of the Apple80211 functions). From that thread I linked to, it looks like you may need to have this installed in /Applications on a jailbroken phone, in order to work fully. Or, possibly have to mess around with adding some entitlements to your sandboxed app.
Solution 3:
These Apple80211xxx functions do not exist in MobileWiFi.framework (you can check using the `nm' tool against the SDK binaries).
(Also, it's impossible to dump a C header from binaries because all type information are removed during compilation. You need to reverse engineer it yourself or wait for someone to do so.)