├── .gitignore
├── Makefile
├── src
├── entitlements.xml
├── Constants.h
├── UtilNetworksManager.h
├── UtilNetwork.h
├── UtilNetwork.m
├── main.m
└── UtilNetworksManager.m
├── README.md
└── headers
└── MobileWiFi
├── MobileWiFi.h
├── WiFiManager.h
├── WiFiNetwork.h
└── WiFiDeviceClient.h
/.gitignore:
--------------------------------------------------------------------------------
1 | .theos/
2 | debs/
3 | control
4 | *.o
5 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | include $(THEOS)/makefiles/common.mk
2 |
3 | TOOL_NAME = wifiutil
4 | wifiutil_FILES = $(wildcard src/*.m*)
5 | wifiutil_PRIVATE_FRAMEWORKS = MobileWiFi
6 | wifiutil_CODESIGN_FLAGS = -Ssrc/entitlements.xml
7 |
8 | ADDITIONAL_CFLAGS = -I$(THEOS_PROJECT_DIR)/headers/
9 |
10 | include $(THEOS_MAKE_PATH)/tool.mk
11 |
--------------------------------------------------------------------------------
/src/entitlements.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.wifi.manager-access
6 |
7 | keychain-access-groups
8 |
9 | apple
10 | com.apple.preferences
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/Constants.h:
--------------------------------------------------------------------------------
1 | // Colors
2 | // Normal "\x1B[0m"
3 | // Red "\x1B[31m"
4 | // Green "\x1B[32m"
5 | // Yellow "\x1B[33m"
6 | // Blue "\x1B[34m"
7 | // CYAN "\x1B[36m"
8 | // White "\x1B[37m"
9 |
10 | #define LOG_DBG(x) \
11 | NSLog(@"\x1B[32m[Debug] \x1B[0m%@", x);
12 | #define LOG_ERR(x) \
13 | NSLog(@"\x1B[31m[Error] \x1B[0m%@", x);
14 | #define LOG_OUTPUT(x) \
15 | NSLog(@"\x1B[36m[Output] \x1B[0m%@", x);
16 |
--------------------------------------------------------------------------------
/src/UtilNetworksManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // UtilNetworksManager.h
3 | //
4 | //
5 | // Created by qpiu on 2016/2/12.
6 | //
7 | //
8 |
9 | #import
10 | #import "MobileWiFi/MobileWiFi.h"
11 |
12 | @class UtilNetwork;
13 |
14 | @interface UtilNetworksManager : NSObject {
15 | WiFiManagerRef _manager;
16 | WiFiDeviceClientRef _client;
17 | WiFiNetworkRef _currentNetwork;
18 | BOOL _scanning;
19 | BOOL _associating;
20 | NSMutableArray *_networks;
21 | int _statusCode;
22 | }
23 |
24 | @property(nonatomic, retain, readonly) NSArray *networks;
25 | @property(nonatomic, assign, readonly, getter = isScanning) BOOL scanning;
26 | @property(nonatomic, assign, readonly) int statusCode;
27 | @property(nonatomic, assign, getter = isWiFiEnabled) BOOL wiFiEnabled;
28 |
29 | + (id)sharedInstance;
30 | - (void)scan;
31 | //- (void)removeNetwork:(UtilNetwork *)network;
32 | - (void)associateWithNetwork:(UtilNetwork *)network;
33 | - (void)associateWithEncNetwork:(UtilNetwork *)network Password:(NSString *)passwd;
34 | - (void)disassociate;
35 | - (UtilNetwork *)getNetworkWithSSID:(NSString *)ssid;
36 | //- (NSArray *)knownNetworks;
37 | //- (NSString *)interfaceName;
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # wifiutil
2 |
3 |
4 |
5 |
6 |
7 | iOS command-line tool for WiFi-related operation.
8 |
9 | # Installation
10 |
11 | - Search
wifiutil in the Cydia on your jailbroken iOS device.
12 | - Install and access it using MobileTerminal or remote SSH.
13 |
14 |
15 | # Usage
16 |
17 | - To enable wifi on iphone:
wifiutil enable-wifi
18 | - To disable wifi on iphone:
wifiutil disable-wifi
19 | - To scan available wifi hotspot:
wifiutil scan
20 | - To associate with wifi hotspot named {ssid}:
wifiutil associate {ssid}
21 | - To associate with wifi hotspot named {ssid} and with password {passwd}:
wifiutil associate {ssid} -p {passwd}
22 | - To disassociate with current wifi network:
wifiutil disassociate
23 | - To ping an ip address:
wifiutil ping {ip}
24 |
25 |
26 | # License
27 | Licensed under:
28 |
29 |
--------------------------------------------------------------------------------
/src/UtilNetwork.h:
--------------------------------------------------------------------------------
1 | //
2 | // UtilNetwork.h
3 | //
4 | //
5 | // Created by qpiu on 2016/2/12.
6 | //
7 | //
8 |
9 | #ifndef UtilNetwork_h
10 | #define UtilNetwork_h
11 |
12 | #import "MobileWiFi/MobileWiFi.h"
13 |
14 | @interface UtilNetwork : NSObject {
15 | WiFiNetworkRef _network;
16 | NSString *_SSID;
17 | NSString *_encryptionModel;
18 | NSString *_BSSID;
19 | NSString *_username;
20 | NSString *_password;
21 | int _channel;
22 | BOOL _isCurrentNetwork;
23 | BOOL _isHidden;
24 | BOOL _isAssociating;
25 | BOOL _requiresUsername;
26 | BOOL _requiresPassword;
27 | }
28 |
29 | @property(nonatomic, copy) NSString *SSID;
30 | @property(nonatomic, copy) NSString *encryptionModel;
31 | @property(nonatomic, copy) NSString *BSSID;
32 | @property(nonatomic, copy) NSString *username;
33 | @property(nonatomic, copy) NSString *password;
34 | @property(nonatomic, assign) int channel;
35 | @property(nonatomic, assign) BOOL isCurrentNetwork;
36 | @property(nonatomic, assign) BOOL isHidden;
37 | @property(nonatomic, assign) BOOL isAssociating;
38 | @property(nonatomic, assign) BOOL requiresPassword;
39 | @property(nonatomic, assign) BOOL requiresUsername;
40 | @property(nonatomic, assign, readonly) WiFiNetworkRef _networkRef;
41 |
42 | - (id)initWithNetwork:(WiFiNetworkRef)network;
43 | - (void)populateData;
44 |
45 |
46 | @end
47 | #endif /* UtilNetwork_h */
48 |
--------------------------------------------------------------------------------
/headers/MobileWiFi/MobileWiFi.h:
--------------------------------------------------------------------------------
1 | /*
2 | * MobileWiFi framework base header.
3 | *
4 | * Copyright (c) 2013-2014 Cykey (David Murray)
5 | * All rights reserved.
6 | */
7 |
8 | #ifndef MOBILEWIFI_H_
9 | #define MOBILEWIFI_H_
10 |
11 | #include "WiFiDeviceClient.h"
12 | #include "WiFiNetwork.h"
13 | #include "WiFiManager.h"
14 |
15 | #if __cplusplus
16 | extern "C" {
17 | #endif
18 |
19 | #pragma mark - Constants
20 |
21 | extern CFStringRef kWiFiATJTestModeEnabledKey;
22 | extern CFStringRef kWiFiDeviceCapabilitiesKey;
23 | extern CFStringRef kWiFiDeviceSupportsWAPIKey;
24 | extern CFStringRef kWiFiDeviceSupportsWoWKey;
25 | extern CFStringRef kWiFiDeviceVendorIDKey;
26 | extern CFStringRef kWiFiLocaleTestParamsKey;
27 | extern CFStringRef kWiFiLoggingDriverFileKey;
28 | extern CFStringRef kWiFiLoggingDriverLoggingEnabledKey;
29 | extern CFStringRef kWiFiLoggingEnabledKey;
30 | extern CFStringRef kWiFiLoggingFileEnabledKey;
31 | extern CFStringRef kWiFiLoggingFileKey;
32 | extern CFStringRef kWiFiManagerDisableBlackListKey;
33 | extern CFStringRef kWiFiNetworkEnterpriseProfileKey;
34 | extern CFStringRef kWiFiPreferenceCustomNetworksSettingsKey;
35 | extern CFStringRef kWiFiPreferenceEnhancedWoWEnabledKey;
36 | extern CFStringRef kWiFiPreferenceMStageAutoJoinKey;
37 | extern CFStringRef kWiFiRSSIThresholdKey; // '-80'
38 | extern CFStringRef kWiFiScaledRSSIKey;
39 | extern CFStringRef kWiFiScaledRateKey;
40 | extern CFStringRef kWiFiStrengthKey;
41 | extern CFStringRef kWiFiTetheringCredentialsKey;
42 |
43 | #if __cplusplus
44 | }
45 | #endif
46 |
47 | #endif /* MOBILEWIFI_H_ */
48 |
--------------------------------------------------------------------------------
/headers/MobileWiFi/WiFiManager.h:
--------------------------------------------------------------------------------
1 | /*
2 | * MobileWiFi manager header.
3 | *
4 | * Copyright (c) 2013-2014 Cykey (David Murray)
5 | * All rights reserved.
6 | */
7 |
8 | #ifndef WIFIMANAGER_H_
9 | #define WIFIMANAGER_H_
10 |
11 | #include
12 | #include "WiFiNetwork.h"
13 | #include "WiFiDeviceClient.h"
14 |
15 | #if __cplusplus
16 | extern "C" {
17 | #endif
18 |
19 | #pragma mark - Definitions
20 |
21 | typedef struct __WiFiManager *WiFiManagerRef;
22 |
23 | #pragma mark - API
24 |
25 | WiFiManagerRef WiFiManagerClientCreate(CFAllocatorRef allocator, int flags);
26 |
27 | CFArrayRef WiFiManagerClientCopyDevices(WiFiManagerRef manager);
28 | CFArrayRef WiFiManagerClientCopyNetworks(WiFiManagerRef manager);
29 |
30 | void WiFiManagerClientRemoveNetwork(WiFiManagerRef manager, WiFiNetworkRef network);
31 |
32 | WiFiDeviceClientRef WiFiManagerClientGetDevice(WiFiManagerRef manager);
33 |
34 | void WiFiManagerClientScheduleWithRunLoop(WiFiManagerRef manager, CFRunLoopRef runLoop, CFStringRef mode);
35 | void WiFiManagerClientUnscheduleFromRunLoop(WiFiManagerRef manager);
36 | void WiFiManagerClientSetProperty(WiFiManagerRef manager, CFStringRef property, CFPropertyListRef value);
37 |
38 | CFPropertyListRef WiFiManagerClientCopyProperty(WiFiManagerRef manager, CFStringRef property);
39 |
40 | void WiFiManagerClientQuiesceWiFi(WiFiManagerRef manager, int state);
41 |
42 | void WiFiManagerClientSetMISState(WiFiManagerRef manager, int state);
43 | void WiFiManagerClientSetMisPassword(WiFiManagerRef manager, CFStringRef password);
44 | void WiFiManagerClientSetMISDiscoveryState(WiFiManagerRef manager, int state);
45 |
46 | int WiFiManagerClientGetMISState(WiFiManagerRef manager);
47 | int WiFiManagerClientGetMISDiscoveryState(WiFiManagerRef manager);
48 |
49 | #if __cplusplus
50 | }
51 | #endif
52 |
53 | #endif /* WIFIMANAGER_H_ */
54 |
--------------------------------------------------------------------------------
/headers/MobileWiFi/WiFiNetwork.h:
--------------------------------------------------------------------------------
1 | /*
2 | * MobileWiFi network header.
3 | *
4 | * Copyright (c) 2013-2014 Cykey (David Murray)
5 | * All rights reserved.
6 | */
7 |
8 | #ifndef WIFINETWORK_H_
9 | #define WIFINETWORK_H_
10 |
11 | #include
12 |
13 | #if __cplusplus
14 | extern "C" {
15 | #endif
16 |
17 | #pragma mark - Definitions
18 |
19 | /*
20 | * Opaque structure definitions.
21 | */
22 |
23 | typedef struct __WiFiNetwork *WiFiNetworkRef;
24 |
25 | #pragma mark - API
26 |
27 | CFPropertyListRef WiFiNetworkGetProperty(WiFiNetworkRef network, CFStringRef property);
28 |
29 | int WiFiNetworkGetIntProperty(WiFiNetworkRef network, CFStringRef property);
30 |
31 | float WiFiNetworkGetFloatProperty(WiFiNetworkRef network, CFStringRef property);
32 |
33 | CFStringRef WiFiNetworkCopyPassword(WiFiNetworkRef);
34 | CFStringRef WiFiNetworkGetSSID(WiFiNetworkRef network);
35 |
36 | void WiFiNetworkSetPassword(WiFiNetworkRef network, CFStringRef password);
37 |
38 | float WiFiNetworkGetNetworkUsage(WiFiNetworkRef network);
39 |
40 | Boolean WiFiNetworkIsWEP(WiFiNetworkRef network);
41 | Boolean WiFiNetworkIsWPA(WiFiNetworkRef network);
42 | Boolean WiFiNetworkIsEAP(WiFiNetworkRef network);
43 | Boolean WiFiNetworkIsApplePersonalHotspot(WiFiNetworkRef network);
44 | Boolean WiFiNetworkIsAdHoc(WiFiNetworkRef network);
45 | Boolean WiFiNetworkIsHidden(WiFiNetworkRef network);
46 | Boolean WiFiNetworkRequiresPassword(WiFiNetworkRef network);
47 | Boolean WiFiNetworkRequiresUsername(WiFiNetworkRef network);
48 |
49 | /* This returns NULL a lot, not sure why. */
50 | CFDateRef WiFiNetworkGetLastAssociationDate(WiFiNetworkRef network);
51 |
52 | CFDictionaryRef WiFiNetworkCopyRecord(WiFiNetworkRef network);
53 |
54 | #if __cplusplus
55 | }
56 | #endif
57 |
58 | #endif /* WIFINETWORK_H_ */
59 |
--------------------------------------------------------------------------------
/src/UtilNetwork.m:
--------------------------------------------------------------------------------
1 | //
2 | // UtilNetwork.m
3 | //
4 | //
5 | // Created by qpiu on 2016/2/12.
6 | //
7 | //
8 |
9 | //#import
10 | #import "UtilNetwork.h"
11 | #import
12 | #import "Constants.h"
13 |
14 | @implementation UtilNetwork
15 | @synthesize _networkRef = _network;
16 | @synthesize SSID = _SSID;
17 | @synthesize encryptionModel = _encryptionModel;
18 | @synthesize BSSID = _BSSID;
19 | @synthesize username = _username;
20 | @synthesize password = _password;
21 | @synthesize channel = _channel;
22 | @synthesize isCurrentNetwork = _isCurrentNetwork;
23 | @synthesize isHidden = _isHidden;
24 | @synthesize isAssociating = _isAssociating;
25 | @synthesize requiresUsername = _requiresUsername;
26 | @synthesize requiresPassword = _requiresPassword;
27 |
28 | - (id)initWithNetwork:(WiFiNetworkRef)network
29 | {
30 | self = [super init];
31 |
32 | if (self) {
33 | _network = (WiFiNetworkRef)CFRetain(network);
34 | }
35 |
36 | return self;
37 | }
38 |
39 | - (void)dealloc
40 | {
41 | [_SSID release];
42 | [_encryptionModel release];
43 | [_username release];
44 | [_password release];
45 | CFRelease(_network);
46 |
47 | [super dealloc];
48 | }
49 |
50 | - (NSString *)description
51 | {
52 | return [NSString stringWithFormat:@"%@ SSID: %@ Encryption Model: %@ Channel: %i CurrentNetwork: %i Hidden: %i Associating: %i", [super description], [self SSID], [self encryptionModel], [self channel], [self isCurrentNetwork], [self isHidden], [self isAssociating]];
53 | }
54 |
55 | - (void)populateData
56 | {
57 | // SSID
58 | NSString *SSID = (NSString *)WiFiNetworkGetSSID(_network);
59 | [self setSSID:SSID];
60 | //NSString *dbg_str = [NSString stringWithFormat:@"setSSID: %@", SSID];
61 | //LOG_DBG(dbg_str);
62 |
63 | // Encryption model
64 | if (WiFiNetworkIsWEP(_network)) {
65 | [self setEncryptionModel:@"WEP"];
66 | //dbg_str = [NSString stringWithFormat:@"setEncryptionModel: %s", "WEP"];
67 | //LOG_DBG(dbg_str);
68 | }
69 | else if (WiFiNetworkIsWPA(_network)) {
70 | [self setEncryptionModel:@"WPA"];
71 | //dbg_str = [NSString stringWithFormat:@"setEncryptionModel: %s", "WPA"];
72 | //LOG_DBG(dbg_str);
73 | }
74 | else {
75 | [self setEncryptionModel:@"None"];
76 | //dbg_str = [NSString stringWithFormat:@"setEncryptionModel: %s", "None"];
77 | //LOG_DBG(dbg_str);
78 | }
79 |
80 | // BSSID
81 | NSString *BSSID = (NSString *)WiFiNetworkGetProperty(_network, CFSTR("BSSID"));
82 | [self setBSSID:BSSID];
83 | //dbg_str = [NSString stringWithFormat:@"setBSSID: %@", BSSID];
84 | //LOG_DBG(dbg_str);
85 |
86 | // Channel
87 | CFNumberRef networkChannel = (CFNumberRef)WiFiNetworkGetProperty(_network, CFSTR("CHANNEL"));
88 | int channel;
89 | CFNumberGetValue(networkChannel, 9, &channel); // 9: kCFNumberIntType
90 | [self setChannel:channel];
91 |
92 | // Hidden
93 | BOOL isHidden = WiFiNetworkIsHidden(_network);
94 | [self setIsHidden:isHidden];
95 |
96 | // Requires username
97 | BOOL requiresUsername = WiFiNetworkRequiresUsername(_network);
98 | [self setRequiresUsername:requiresUsername];
99 |
100 | // Requires password
101 | BOOL requiresPassword = WiFiNetworkRequiresPassword(_network);
102 | [self setRequiresPassword:requiresPassword];
103 | }
104 |
105 | @end
106 |
--------------------------------------------------------------------------------
/headers/MobileWiFi/WiFiDeviceClient.h:
--------------------------------------------------------------------------------
1 | /*
2 | * MobileWiFi device client header.
3 | *
4 | * Copyright (c) 2013-2014 Cykey (David Murray)
5 | * All rights reserved.
6 | */
7 |
8 | #ifndef WIFIDEVICECLIENT_H_
9 | #define WIFIDEVICECLIENT_H_
10 |
11 | #include
12 | #include "WiFiNetwork.h"
13 |
14 | #if __cplusplus
15 | extern "C" {
16 | #endif
17 |
18 | #pragma mark - Definitions
19 |
20 | /*
21 | * Opaque structure definition.
22 | */
23 |
24 | typedef struct __WiFiDeviceClient *WiFiDeviceClientRef;
25 |
26 | /* Callback typedefs. */
27 | typedef void (*WiFiDeviceClientGenericCallback)(WiFiDeviceClientRef device, CFDictionaryRef data, const void *object);
28 | typedef void (*WiFiDeviceClientLinkOrPowerCallback)(WiFiDeviceClientRef device, const void *object);
29 | typedef void (*WiFiDeviceScanCallback)(WiFiDeviceClientRef device, CFArrayRef results, int error, const void *object);
30 | typedef void (*WiFiDeviceAssociateCallback)(WiFiDeviceClientRef device, WiFiNetworkRef network, CFDictionaryRef dict, int error, const void *object);
31 |
32 | #pragma mark - API
33 |
34 | CFPropertyListRef WiFiDeviceClientCopyProperty(WiFiDeviceClientRef client, CFStringRef property);
35 |
36 | WiFiNetworkRef WiFiDeviceClientCopyCurrentNetwork(WiFiDeviceClientRef client);
37 |
38 | int WiFiDeviceClientGetPower(WiFiDeviceClientRef client);
39 | void WiFiDeviceClientSetPower(WiFiDeviceClientRef client, int power);
40 |
41 | /*
42 | * The following keys in the dict parameter are understood by wifid:
43 | * "SCAN_CHANNELS": An array of dictionaries containing the 'CHANNEL' and 'CHANNEL_FLAGS' keys.
44 | * "SCAN_MAXAGE": Unknown. Use 2.
45 | * "SCAN_MERGE": Unknown. Use 1.
46 | * "SCAN_NUM_SCANS": Number of scans to perform.
47 | * "SCAN_PHY_MODE": Has something to do with PHY.
48 | * "SCAN_RSSI_THRESHOLD": The RSSI theshold level. Apple uses -80, meaning that networks that have a signal strength lower than -80 will be ignored.
49 | * "SCAN_TYPE": Unknown. Use 1.
50 | */
51 | int WiFiDeviceClientScanAsync(WiFiDeviceClientRef device, CFDictionaryRef dict, WiFiDeviceScanCallback callback, const void *object);
52 |
53 | /*
54 | * Used to connect to a network. Example usage:
55 | * (Get a WiFiNetworkRef instance from the scan results or something.)
56 | * WiFiNetworkSetPassword(network, CFSTR("Password1"));
57 | * WiFiDeviceClientAssociateAsync(client, network, MyCallbackFunction, NULL);
58 | */
59 | int WiFiDeviceClientAssociateAsync(WiFiDeviceClientRef client, WiFiNetworkRef network, WiFiDeviceAssociateCallback callback, CFDictionaryRef dict);
60 | void WiFiDeviceClientAssociateCancel(WiFiDeviceClientRef client);
61 | int WiFiDeviceClientDisassociate(WiFiDeviceClientRef client);
62 |
63 | CFStringRef WiFiDeviceClientGetInterfaceName(WiFiDeviceClientRef client);
64 |
65 | /*
66 | * LQM stands for 'Link Quality Metrics':
67 | * Jan 23 15:25:01 kernel[0] : 187357.621783 wlan.A[13651] AppleBCMWLANNetManager::updateLinkQualityMetrics(): Report LQM to User Land 50, fAverageRSSI -71
68 | */
69 |
70 | void WiFiDeviceClientRegisterLQMCallback(WiFiDeviceClientRef device, WiFiDeviceClientGenericCallback callback, const void *object);
71 | void WiFiDeviceClientRegisterExtendedLinkCallback(WiFiDeviceClientRef device, WiFiDeviceClientGenericCallback callback, const void *object);
72 | void WiFiDeviceClientRegisterLinkCallback(WiFiDeviceClientRef device, WiFiDeviceClientLinkOrPowerCallback callback, const void *object);
73 | void WiFiDeviceClientRegisterPowerCallback(WiFiDeviceClientRef device, WiFiDeviceClientLinkOrPowerCallback callback, const void *object);
74 |
75 | #if __cplusplus
76 | }
77 | #endif
78 |
79 | #endif /* WIFIDEVICECLIENT_H_ */
80 |
--------------------------------------------------------------------------------
/src/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.c
3 | // wifiutil
4 | //
5 | // Created by qpiu on 2016/2/9.
6 | // Copyright (c) 2016年 orangegogo. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import
12 | #import
13 | #import "UtilNetwork.h"
14 | #import "UtilNetworksManager.h"
15 | #import "Constants.h"
16 | #include
17 |
18 | //static WiFiManagerRef _manager;
19 | //static void scan_callback(WiFiDeviceClientRef device, CFArrayRef results, CFErrorRef error, void *token);
20 | //static void scan_networks();
21 |
22 | int getUsageType(NSString *usage);
23 | void printUsage();
24 |
25 | int main(int argc, char **argv, char **envp) {
26 | // insert code here...
27 | NSString *hello = @"Hello, wifiutil! Type \x1B[32mwifiutil help \x1B[0mto see usage.";
28 | LOG_OUTPUT(hello);
29 | NSString *str = [NSString stringWithFormat:@"argc = %d", argc];
30 | //LOG_DBG(str);
31 | /*for (int i = 1; i < argc; i++) {
32 | NSString *str = [NSString stringWithFormat:@"argv[%d] = %s", i, argv[i]];
33 | LOG_DBG(str);
34 | }*/
35 |
36 | if (argc < 2) {
37 | LOG_ERR(@"Specify arguments to use wifiutil.");
38 | return -1;
39 | }
40 |
41 | NSString *usage = [NSString stringWithUTF8String:argv[1]];
42 | str = [NSString stringWithFormat:@"wifiutil: %@", usage];
43 | LOG_DBG(str);
44 | int usageType = getUsageType(usage);
45 | switch (usageType)
46 | {
47 | case 0: // scan
48 | [[UtilNetworksManager sharedInstance] scan];
49 | break;
50 | case 1: // associate: wifiutil associate || wifiutil associate -p
51 | // Argument parsing
52 | if (argc < 3) {
53 | LOG_ERR(@"Specify SSID to use wifiutil to associate.");
54 | return -1;
55 | }
56 | NSString *conn_SSID = [NSString stringWithUTF8String:argv[2]];
57 | NSString *passwd = nil;
58 | if (argc > 3) { // associate with encrypted network
59 | if (argc == 4) {
60 | LOG_ERR(@"Invalid argument format.");
61 | return -1;
62 | }
63 | if ( [[NSString stringWithUTF8String:argv[3]] isEqualToString:@"-p"] ) {
64 | passwd = [NSString stringWithUTF8String:argv[4]];
65 | str = [NSString stringWithFormat:@"Prepare to associate with network %@, passwd: %@", conn_SSID, passwd];
66 | LOG_DBG(str);
67 | }
68 | else {
69 | LOG_ERR(@"Invalid argument format.");
70 | return -1;
71 | }
72 | }
73 | else { // associate with open network
74 | str = [NSString stringWithFormat:@"Prepare to associate with network %@", conn_SSID];
75 | LOG_DBG(str);
76 | }
77 |
78 | // Scan networks first, and get the network instance with the specified SSID.
79 | UtilNetworksManager *manager = [UtilNetworksManager sharedInstance];
80 | [manager scan];
81 |
82 | UtilNetwork *conn_Network = [manager getNetworkWithSSID: conn_SSID];
83 | if (conn_Network)
84 | {
85 | str = [NSString stringWithFormat:@"Found network %@ :)", [conn_Network SSID]];
86 | LOG_OUTPUT(str);
87 | if ( [[conn_Network encryptionModel] isEqualToString:@"None"]) { // Open network
88 | [manager associateWithNetwork: conn_Network];
89 | }
90 | else if ( ![[conn_Network encryptionModel] isEqualToString:@"None"]) { // Encrypted network
91 | if (!passwd)
92 | {
93 | LOG_ERR(@"Specify PASSWORD to use associate with encrypted network.");
94 | [manager dealloc];
95 | return -1;
96 | }
97 | [manager associateWithEncNetwork: conn_Network Password: passwd];
98 | }
99 | }
100 | else
101 | {
102 | str = [NSString stringWithFormat:@"Can not find network %@ :(", conn_SSID];
103 | LOG_ERR(str);
104 | [manager dealloc];
105 | return -1;
106 | }
107 | break;
108 |
109 | case 2: // disassociate
110 | [[UtilNetworksManager sharedInstance] disassociate];
111 | break;
112 |
113 | case 3: // enable-wifi
114 | //UtilNetworksManager *manager = [UtilNetworksManager sharedInstance];
115 | str = [NSString stringWithFormat:@"Enable WiFi on iPhone."];
116 | LOG_DBG(str);
117 | [[UtilNetworksManager sharedInstance] setWiFiEnabled: YES];
118 | break;
119 |
120 | case 4: // disable-wifi
121 | //UtilNetworksManager *manager = [UtilNetworksManager sharedInstance];
122 | str = [NSString stringWithFormat:@"Disable WiFi on iPhone."];
123 | LOG_DBG(str);
124 | [[UtilNetworksManager sharedInstance] setWiFiEnabled: NO];
125 | break;
126 |
127 | case 5: // ping
128 | if (argc < 3) {
129 | LOG_ERR(@"Specify IP to use wifiutil to ping.\n");
130 | return -1;
131 | }
132 | NSString *ping_ip = [NSString stringWithUTF8String:argv[2]];
133 |
134 | // execute ping
135 | NSPipe *pipe = [NSPipe pipe];
136 | NSFileHandle *file = pipe.fileHandleForReading;
137 |
138 | NSTask *task = [[NSTask alloc] init];
139 | task.launchPath = @"/usr/bin/ping";
140 | task.arguments = @[@"-i", @"0.2", @"-c", @"50", ping_ip];
141 | task.standardOutput = pipe;
142 | [task launch];
143 |
144 | NSData *data = [file readDataToEndOfFile];
145 | [file closeFile];
146 | NSString *output = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
147 | LOG_OUTPUT(output);
148 | LOG_OUTPUT(@"Ping Finished !");
149 | break;
150 |
151 | case 6: // help
152 | printUsage();
153 | break;
154 |
155 | default:
156 | LOG_ERR(@"Invalid usage >__< ");
157 | break;
158 | }
159 |
160 | return 0;
161 | }
162 |
163 | int getUsageType(NSString *usage)
164 | {
165 | if ([usage isEqualToString:@"scan"]) {
166 | return 0;
167 | }
168 | else if ([usage isEqualToString:@"associate"]) {
169 | return 1;
170 | }
171 | else if ([usage isEqualToString:@"disassociate"]) {
172 | return 2;
173 | }
174 | else if ([usage isEqualToString:@"enable-wifi"]) {
175 | return 3;
176 | }
177 | else if ([usage isEqualToString:@"disable-wifi"]) {
178 | return 4;
179 | }
180 | else if ([usage isEqualToString:@"ping"]) {
181 | return 5;
182 | }
183 | else if ([usage isEqualToString:@"help"]) {
184 | return 6;
185 | }
186 | else {
187 | return -1;
188 | }
189 | }
190 |
191 | void printUsage()
192 | {
193 | NSString *usage = @"\n########## WifiUtil Usage ##########";
194 | usage = [NSString stringWithFormat:@"%@\nScan available wifi hotspots:", usage];
195 | usage = [NSString stringWithFormat:@"%@\n\t\t\x1B[36mwifiutil scan\x1B[0m", usage];
196 | usage = [NSString stringWithFormat:@"%@\nEnable wifi on iPhone:", usage];
197 | usage = [NSString stringWithFormat:@"%@\n\t\t\x1B[36mwifiutil enable-wifi\x1B[0m", usage];
198 | usage = [NSString stringWithFormat:@"%@\nDisable wifi on iPhone:", usage];
199 | usage = [NSString stringWithFormat:@"%@\n\t\t\x1B[36mwifiutil disable-wifi\x1B[0m", usage];
200 | usage = [NSString stringWithFormat:@"%@\nAssociate to wifi:", usage];
201 | usage = [NSString stringWithFormat:@"%@\n\t\t\x1B[36mwifiutil associate \x1B[0m--> For wifi networks without password\x1B[0m", usage];
202 | usage = [NSString stringWithFormat:@"%@\n\t\t\x1B[36mwifiutil associate -p \x1B[0m--> For wifi networks with password\x1B[0m", usage];
203 | usage = [NSString stringWithFormat:@"%@\nDisassociate with current wifi network:", usage];
204 | usage = [NSString stringWithFormat:@"%@\n\t\t\x1B[36mwifiutil disassociate\x1B[0m", usage];
205 | NSLog(@"%@", usage);
206 |
207 | return;
208 | }
209 |
210 | /*static void scan_networks()
211 | {
212 | _manager = WiFiManagerClientCreate(kCFAllocatorDefault, 0);
213 |
214 | CFArrayRef devices = WiFiManagerClientCopyDevices(_manager);
215 | if (!devices) {
216 | fprintf(stderr, "Couldn't get WiFi devices. Bailing.\n");
217 | exit(EXIT_FAILURE);
218 | }
219 |
220 | WiFiDeviceClientRef client = (WiFiDeviceClientRef)CFArrayGetValueAtIndex(devices, 0);
221 |
222 | WiFiManagerClientScheduleWithRunLoop(_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
223 | WiFiDeviceClientScanAsync(client, (CFDictionaryRef)[NSDictionary dictionary], (WiFiDeviceScanCallback)scan_callback, 0);
224 |
225 | CFRelease(devices);
226 |
227 | CFRunLoopRun();
228 | }
229 |
230 | static void scan_callback(WiFiDeviceClientRef device, CFArrayRef results, CFErrorRef error, void *token)
231 | {
232 | NSLog(@"Finished scanning! networks: %@", results);
233 |
234 | WiFiManagerClientUnscheduleFromRunLoop(_manager);
235 | CFRelease(_manager);
236 |
237 | CFRunLoopStop(CFRunLoopGetCurrent());
238 | }*/
239 |
240 | // vim:ft=objc
241 |
--------------------------------------------------------------------------------
/src/UtilNetworksManager.m:
--------------------------------------------------------------------------------
1 | //
2 | // UtilNetworksManager.m
3 | //
4 | //
5 | // Created by qpiu on 2016/2/12.
6 | //
7 | //
8 |
9 | #import "UtilNetworksManager.h"
10 | #import "UtilNetwork.h"
11 | #import "Constants.h"
12 |
13 | @interface UtilNetworksManager ()
14 |
15 | - (void)_scan;
16 | - (void)_clearNetworks;
17 | - (void)_addNetwork:(UtilNetwork *)network;
18 | - (void)_reloadCurrentNetwork;
19 | - (void)_scanDidFinishWithError:(int)error;
20 | - (void)_associationDidFinishWithError:(int)error;
21 | - (WiFiNetworkRef)_currentNetwork;
22 |
23 | static void UtilScanCallback(WiFiDeviceClientRef device, CFArrayRef results, CFErrorRef error, void *token);
24 | static void UtilAssociationCallback(WiFiDeviceClientRef device, WiFiNetworkRef networkRef, CFDictionaryRef dict, CFErrorRef error, void *token);
25 |
26 | @end
27 |
28 | static UtilNetworksManager *_sharedInstance = nil;
29 |
30 | @implementation UtilNetworksManager
31 | @synthesize networks = _networks;
32 | @synthesize scanning = _scanning;
33 | @synthesize statusCode = _statusCode;
34 |
35 | + (id)sharedInstance
36 | {
37 | @synchronized(self) {
38 | if (!_sharedInstance)
39 | _sharedInstance = [[self alloc] init];
40 |
41 | return _sharedInstance;
42 | }
43 | }
44 |
45 | - (id)init
46 | {
47 | self = [super init];
48 |
49 | if (self) {
50 | _manager = WiFiManagerClientCreate(kCFAllocatorDefault, 0);
51 | CFArrayRef devices = WiFiManagerClientCopyDevices(_manager);
52 | if (!devices) {
53 | fprintf(stderr, "Couldn't get WiFi devices. Bailing.\n");
54 | exit(EXIT_FAILURE);
55 | }
56 |
57 | _client = (WiFiDeviceClientRef)CFArrayGetValueAtIndex(devices, 0);
58 | CFRetain(_client);
59 | CFRelease(devices);
60 |
61 | _networks = [[NSMutableArray alloc] init];
62 | }
63 |
64 | return self;
65 | }
66 |
67 | - (void)dealloc
68 | {
69 | //CFNotificationCenterRemoveObserver(CFNotificationCenterGetDarwinNotifyCenter(), self, NULL, NULL);
70 |
71 | CFRelease(_currentNetwork);
72 | CFRelease(_client);
73 | CFRelease(_manager);
74 |
75 | [self _clearNetworks];
76 |
77 | [super dealloc];
78 | }
79 |
80 | - (void)scan
81 | {
82 | _statusCode = -1;
83 | // If WiFi is off
84 | if(![self isWiFiEnabled]) {
85 | [self setWiFiEnabled: YES];
86 | [NSThread sleepForTimeInterval:5];
87 | }
88 |
89 | // Prevent initiating a scan when we're already scanning.
90 | if (_scanning)
91 | return;
92 | _scanning = YES;
93 |
94 | // Reload the current network.
95 | [self _reloadCurrentNetwork];
96 |
97 | // Actually initiate a scan.
98 | [self _scan];
99 | }
100 |
101 | - (void)associateWithNetwork:(UtilNetwork *)network
102 | {
103 | _statusCode = -1;
104 | // Prevent initiating an association if we're already associating.
105 | if (_associating) {
106 | LOG_DBG(@"already associating...stop");
107 | return;
108 | }
109 |
110 | if (_currentNetwork) {
111 | LOG_DBG(@"Disassociate with the current network");
112 | [self disassociate];
113 | }
114 |
115 | WiFiManagerClientScheduleWithRunLoop(_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
116 |
117 | WiFiNetworkRef net = [network _networkRef];
118 | if(!net)
119 | LOG_ERR(@"Cannot get networkRef");
120 |
121 | [network setIsAssociating:YES];
122 | _associating = YES;
123 | LOG_DBG(@"Start associating");
124 | WiFiDeviceClientAssociateAsync(_client, net, (WiFiDeviceAssociateCallback)UtilAssociationCallback, 0);
125 | CFRunLoopRun();
126 | }
127 |
128 | - (void)associateWithEncNetwork:(UtilNetwork *)network Password:(NSString *)passwd
129 | {
130 | _statusCode = -1;
131 | // Prevent initiating an association if we're already associating.
132 | if (_associating) {
133 | LOG_DBG(@"already associating...stop");
134 | return;
135 | }
136 |
137 | if (_currentNetwork) {
138 | // Disassociate with the current network before association.
139 | LOG_DBG(@"Disassociate with the current network");
140 | [self disassociate];
141 | }
142 |
143 | WiFiManagerClientScheduleWithRunLoop(_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
144 |
145 | WiFiNetworkRef net = [network _networkRef];
146 | if(!net)
147 | LOG_ERR(@"Cannot get networkRef");
148 |
149 | WiFiNetworkSetPassword(net, (__bridge CFStringRef)passwd);
150 |
151 | [network setIsAssociating:YES];
152 | _associating = YES;
153 | LOG_DBG(@"Start associating");
154 | WiFiDeviceClientAssociateAsync(_client, net, (WiFiDeviceAssociateCallback)UtilAssociationCallback, 0);
155 | CFRunLoopRun();
156 |
157 | }
158 |
159 | - (BOOL)isWiFiEnabled
160 | {
161 | CFBooleanRef enabled = WiFiManagerClientCopyProperty(_manager, CFSTR("AllowEnable"));
162 | BOOL value = CFBooleanGetValue(enabled);
163 | CFRelease(enabled);
164 | return value;
165 | }
166 |
167 | - (void)setWiFiEnabled:(BOOL)enabled
168 | {
169 | CFBooleanRef value = (enabled ? kCFBooleanTrue : kCFBooleanFalse);
170 | WiFiManagerClientSetProperty(_manager, CFSTR("AllowEnable"), value);
171 | return;
172 | }
173 |
174 | - (void)disassociate
175 | {
176 | WiFiDeviceClientDisassociate(_client);
177 | }
178 |
179 | - (UtilNetwork *)getNetworkWithSSID:(NSString *)ssid
180 | {
181 | for(UtilNetwork *network in _networks)
182 | {
183 | if( [[network SSID] isEqualToString:ssid] )
184 | return network; // network exists
185 | }
186 | return nil; // cannot find the network
187 | }
188 |
189 | - (NSString *)prettyPrintNetworks
190 | {
191 | NSString *output = [[NSString alloc] init];
192 | NSString *str = [[NSString alloc] init];
193 |
194 | for(UtilNetwork *network in _networks)
195 | {
196 | str = [NSString stringWithFormat:@" %30s\t| %20s\t| %s %d\t", [[network SSID] UTF8String], [[network BSSID] UTF8String], "channel", [network channel]];
197 | output = [NSString stringWithFormat:@"%@\n%@", output, str];
198 | }
199 | return output;
200 | }
201 |
202 | #pragma mark - Private APIs
203 |
204 | - (void)_scan
205 | {
206 | //LOG_DBG(@"Scanning...\n");
207 | WiFiManagerClientScheduleWithRunLoop(_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
208 | WiFiDeviceClientScanAsync(_client, (CFDictionaryRef)[NSDictionary dictionary], (WiFiDeviceScanCallback)UtilScanCallback, 0);
209 | CFRunLoopRun();
210 | }
211 |
212 | - (void)_clearNetworks
213 | {
214 | [_networks removeAllObjects];
215 | }
216 |
217 | - (void)_addNetwork:(UtilNetwork *)network
218 | {
219 | [_networks addObject:network];
220 | }
221 |
222 | - (WiFiNetworkRef)_currentNetwork
223 | {
224 | return _currentNetwork;
225 | }
226 |
227 | - (void)_reloadCurrentNetwork
228 | {
229 | if (_currentNetwork) {
230 | CFRelease(_currentNetwork);
231 | _currentNetwork = nil;
232 | }
233 |
234 | _currentNetwork = WiFiDeviceClientCopyCurrentNetwork(_client);
235 | }
236 |
237 | - (void)_scanDidFinishWithError:(int)error
238 | {
239 | WiFiManagerClientUnscheduleFromRunLoop(_manager);
240 | //NSString *str = [NSString stringWithFormat:@"Scanning finished code: %d", error];
241 | //LOG_DBG(str);
242 | _statusCode = error;
243 | if (_statusCode == 0) {
244 | LOG_OUTPUT(@"Scanning is successful :) ");
245 | }
246 | else if (_statusCode < 0) {
247 | LOG_DBG(@"Scanning failed :( ");
248 | }
249 | _scanning = NO;
250 | }
251 |
252 | - (void)_associationDidFinishWithError:(int)error
253 | {
254 | WiFiManagerClientUnscheduleFromRunLoop(_manager);
255 |
256 | for (UtilNetwork *network in [[UtilNetworksManager sharedInstance] networks]) {
257 | if ([network isAssociating])
258 | [network setIsAssociating:NO];
259 | }
260 | //NSString *str = [NSString stringWithFormat:@"Association finished code: %d", error];
261 | //LOG_DBG(str);
262 | _statusCode = error;
263 | if (_statusCode == 0) {
264 | LOG_OUTPUT(@"Association is successful :) ");
265 | }
266 | else if (_statusCode < 0) {
267 | LOG_DBG(@"Association failed :( ");
268 | }
269 |
270 | _associating = NO;
271 | // Reload the current network.
272 | [self _reloadCurrentNetwork];
273 | }
274 |
275 | #pragma mark - Functions
276 |
277 | static void UtilScanCallback(WiFiDeviceClientRef device, CFArrayRef results, CFErrorRef error, void *token)
278 | {
279 | //NSString *str = [NSString stringWithFormat:@"Finished scanning! %lu networks: %@", (unsigned long)[(__bridge NSArray *)results count], results];
280 | //LOG_OUTPUT(str);
281 | CFRunLoopStop(CFRunLoopGetCurrent());
282 |
283 | [[UtilNetworksManager sharedInstance] _clearNetworks];
284 | for (unsigned x = 0; x < CFArrayGetCount(results); x++) {
285 | WiFiNetworkRef networkRef = (WiFiNetworkRef)CFArrayGetValueAtIndex(results, x);
286 |
287 | UtilNetwork *network = [[UtilNetwork alloc] initWithNetwork:networkRef];
288 | [network populateData];
289 |
290 | WiFiNetworkRef currentNetwork = [[UtilNetworksManager sharedInstance] _currentNetwork];
291 |
292 | // WiFiNetworkGetProperty() crashes if the network parameter is NULL therefore we need to check if it exists first.
293 | if (currentNetwork) {
294 | if ([[network BSSID] isEqualToString:(NSString *)WiFiNetworkGetProperty(currentNetwork, CFSTR("BSSID"))])
295 | [network setIsCurrentNetwork:YES];
296 | }
297 |
298 | BOOL netExists = 0;
299 | for (UtilNetwork *n in [[UtilNetworksManager sharedInstance] networks])
300 | {
301 | if ( [[n BSSID] isEqualToString: [network BSSID]] ) {
302 | netExists = 1;
303 | NSString *str = [NSString stringWithFormat:@"(%@, %@) is already exists.", [network SSID], [network BSSID]];
304 | LOG_DBG(str);
305 | break; // network is already in _networks
306 | }
307 | }
308 | if (!netExists)
309 | [[UtilNetworksManager sharedInstance] _addNetwork: network];
310 |
311 | [network release];
312 | }
313 | NSString *str = [NSString stringWithFormat:@"Finished scanning! %lu networks: %@",
314 | (unsigned long)[[[UtilNetworksManager sharedInstance] networks] count], [[UtilNetworksManager sharedInstance] prettyPrintNetworks]];
315 | LOG_OUTPUT(str);
316 | [[UtilNetworksManager sharedInstance] _scanDidFinishWithError:(int)error];
317 | }
318 |
319 | static void UtilAssociationCallback(WiFiDeviceClientRef device, WiFiNetworkRef networkRef, CFDictionaryRef dict, CFErrorRef error, void *token)
320 | {
321 | CFRunLoopStop(CFRunLoopGetCurrent());
322 | // Reload every network's data.
323 | for (UtilNetwork *network in [[UtilNetworksManager sharedInstance] networks]) {
324 | [network populateData];
325 |
326 | if (networkRef) {
327 | [network setIsCurrentNetwork:[[network BSSID] isEqualToString:(NSString *)WiFiNetworkGetProperty(networkRef, CFSTR("BSSID"))]];
328 | }
329 | }
330 |
331 | [[UtilNetworksManager sharedInstance] _associationDidFinishWithError:(int)error];
332 |
333 | }
334 |
335 | /*static void UtilReceivedNotification(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
336 | {
337 | [(UtilNetworksManager *)observer _receivedNotificationNamed:(NSString *)name];
338 | }*/
339 |
340 | @end
341 |
--------------------------------------------------------------------------------