At some point, my apmode utility got dropped from Erica Utilities and a number of people, particularly my pal Pytey, asked if I could find some time to bring it back to life. Last night, I decided to see if I could put this together using 2.x technology after having put this off for far too long.
In its first iteration, apmode used dynamic linking to access functions in the public Preferences framework. With 2.0, Preferences had been moved to Private Frameworks and I assumed that it more or less offered the same functionality. This assumption was wrong.
In fact, Airport control was moved by Apple into a separate framework, another private framework called SpringBoardServices, which offers many features specific to SpringBoard operations. It handles watchdogs, the status bar, badging and more, bringing many features out of the SpringBoard application and into a more general library, presumably that can be accessed by other Apple applications.
After running nm to get a symbol dump, I found a reference to two different Airplane functions: SBEnableAirplaneMode and SBSetAirplaneModeEnabled. I'll spare you the reverse engineering details other than to say that you do in fact have to supply a mach port to the function as you normally do with UIKit calls in order for the function to work. In its past, Preferences-based life, the Airplane function just took a single argument, a boolean. The new version, takes both the port and the boolean instead.
So here's the final working code. It makes two dynamic links, first to UIKit to retrieve the port and second to the SpringBoardServices to set the Airplane mode to either off or on. When you test this, make sure you do some sort of "set it off, sleep, then turn it back on" command otherwise you'll lock yourself out of your ongoing secure shell session.
This is for you, Pytey.
#import <UIKit/UIKit.h>
#import <UIKit/UIApplication.h>
#include <dlfcn.h>
#include <stdio.h>
// Framework Paths
#define SBSERVPATH "/System/Library/PrivateFrameworks/SpringBoardServices.framework/SpringBoardServices"
#define UIKITPATH "/System/Library/Framework/UIKit.framework/UIKit"
int main(int argc, char **argv)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
//
// For testing try issuing the following:
// ap y; sleep 5; ./ap n
//
if (argc < 2)
{
printf("Usage: %s (y | n)\n", argv[0]);
exit(-1);
}
// Argument used to switch airplane mode off or on
BOOL yorn = [[[NSString stringWithCString:argv[1]]
uppercaseString] hasPrefix:@"Y"];
// Fetch the SpringBoard server port
mach_port_t *p;
void *uikit = dlopen(UIKITPATH, RTLD_LAZY);
int (*SBSSpringBoardServerPort)() =
dlsym(uikit, "SBSSpringBoardServerPort");
p = SBSSpringBoardServerPort();
dlclose(uikit);
// Link to SBSetAirplaneModeEnabled
void *sbserv = dlopen(SBSERVPATH, RTLD_LAZY);
int (*setAPMode)(mach_port_t* port, BOOL yorn) =
dlsym(sbserv, "SBSetAirplaneModeEnabled");
setAPMode(p, yorn);
dlclose(sbserv);
[pool release];
}
Thank you Erica,
I would be curious to learn more about the reverse engineering that goes into understanding how all these pieces work. I ran nm and can see the references to the symbols. How does one go about figuring out the remaining code/calls to pull all this together?
I've found some generic content online for reverse engineering Cocoa, however, a walk through from beginning to end of a simple example would be of great help!
Also, will this code run on device and toggle the airplane mode (with changes of course to read the current settings)?
Thank you!
John Muchow
http://iPhoneDeveloperTips.com
I was wondering with the use of new features such as Southwest Airline's WiFi being testing if this would affect the "airplane mode" many people currently still have on their phones. Even though Southwest is currently in the testing phase I’m sure private jet services either already have these capabilities or are going to look into them in the near future. If Southwest and private jet services fully take on WiFi do you think that this is going to wipe out the use of "airplane mode" on cellular devices?
How about SDK 3.0?
This solution does not work on 3.0. Is there a way of doing it in OS 3.0?
Thanks in advance.