diff --git a/src/android/wifiwizard2/WifiWizard2.java b/src/android/wifiwizard2/WifiWizard2.java index 771059f..6c9483f 100644 --- a/src/android/wifiwizard2/WifiWizard2.java +++ b/src/android/wifiwizard2/WifiWizard2.java @@ -371,11 +371,13 @@ private boolean add(CallbackContext callbackContext, JSONArray data) { String newPass = data.getString(2); boolean isHiddenSSID = data.getBoolean(3); + Log.d(TAG, "SET SSID: " + newSSID); + wifi.hiddenSSID = isHiddenSSID; - if (authType.equals("WPA") || authType.equals("WPA2")) { + if (authType.equals("WPA2")) { /** - * WPA Data format: + * WPA2 Data format: * 0: ssid * 1: auth * 2: password @@ -393,7 +395,28 @@ private boolean add(CallbackContext callbackContext, JSONArray data) { wifi.allowedProtocols.set(WifiConfiguration.Protocol.RSN); wifi.allowedProtocols.set(WifiConfiguration.Protocol.WPA); - wifi.networkId = ssidToNetworkId(newSSID); + wifi.networkId = ssidToNetworkId(newSSID, authType); + + } else if (authType.equals("WPA")) { + /** + * WPA Data format: + * 0: ssid + * 1: auth + * 2: password + * 3: isHiddenSSID + */ + wifi.SSID = newSSID; + wifi.preSharedKey = newPass; + + wifi.status = WifiConfiguration.Status.ENABLED; + wifi.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP); + wifi.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); + wifi.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); + wifi.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP); + wifi.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP); + wifi.allowedProtocols.set(WifiConfiguration.Protocol.WPA); + + wifi.networkId = ssidToNetworkId(newSSID, authType); } else if (authType.equals("WEP")) { /** @@ -425,7 +448,7 @@ private boolean add(CallbackContext callbackContext, JSONArray data) { wifi.allowedProtocols.set(WifiConfiguration.Protocol.RSN); wifi.allowedProtocols.set(WifiConfiguration.Protocol.WPA); - wifi.networkId = ssidToNetworkId(newSSID); + wifi.networkId = ssidToNetworkId(newSSID, authType); } else if (authType.equals("NONE")) { /** @@ -437,7 +460,7 @@ private boolean add(CallbackContext callbackContext, JSONArray data) { */ wifi.SSID = newSSID; wifi.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); - wifi.networkId = ssidToNetworkId(newSSID); + wifi.networkId = ssidToNetworkId(newSSID, authType); } else { @@ -446,7 +469,6 @@ private boolean add(CallbackContext callbackContext, JSONArray data) { return false; } - // Set network to highest priority (deprecated in API >= 26) if( API_VERSION < 26 ){ wifi.priority = getMaxWifiPriority(wifiManager) + 1; @@ -507,18 +529,20 @@ private void enable(CallbackContext callbackContext, JSONArray data) { String ssidToEnable = ""; String bindAll = "false"; String waitForConnection = "false"; + String authType = ""; try { ssidToEnable = data.getString(0); bindAll = data.getString(1); waitForConnection = data.getString(2); + authType = data.getString(3); } catch (Exception e) { callbackContext.error(e.getMessage()); Log.d(TAG, e.getMessage()); return; } - int networkIdToEnable = ssidToNetworkId(ssidToEnable); + int networkIdToEnable = ssidToNetworkId(ssidToEnable, authType); try { @@ -576,16 +600,18 @@ private boolean disable(CallbackContext callbackContext, JSONArray data) { } String ssidToDisable = ""; + String authType = ""; try { ssidToDisable = data.getString(0); + authType = data.getString(1); } catch (Exception e) { callbackContext.error(e.getMessage()); Log.d(TAG, e.getMessage()); return false; } - int networkIdToDisconnect = ssidToNetworkId(ssidToDisable); + int networkIdToDisconnect = ssidToNetworkId(ssidToDisable, authType); try { @@ -631,8 +657,9 @@ private boolean remove(CallbackContext callbackContext, JSONArray data) { // TODO: Verify the type of data! try { String ssidToDisconnect = data.getString(0); + String authType = data.getString(1); - int networkIdToRemove = ssidToNetworkId(ssidToDisconnect); + int networkIdToRemove = ssidToNetworkId(ssidToDisconnect, authType); if (networkIdToRemove > -1) { @@ -680,17 +707,19 @@ private void connect(CallbackContext callbackContext, JSONArray data) { String ssidToConnect = ""; String bindAll = "false"; - + String authType = ""; try { ssidToConnect = data.getString(0); bindAll = data.getString(1); + authType = data.getString(2); + } catch (Exception e) { callbackContext.error(e.getMessage()); Log.d(TAG, e.getMessage()); return; } - int networkIdToConnect = ssidToNetworkId(ssidToConnect); + int networkIdToConnect = ssidToNetworkId(ssidToConnect, authType); if (networkIdToConnect > -1) { // We disable the network before connecting, because if this was the last connection before @@ -803,17 +832,19 @@ private boolean disconnectNetwork(CallbackContext callbackContext, JSONArray dat } String ssidToDisconnect = ""; + String authType = ""; // TODO: Verify type of data here! try { ssidToDisconnect = data.getString(0); + authType = data.getString(1); } catch (Exception e) { callbackContext.error(e.getMessage()); Log.d(TAG, e.getMessage()); return false; } - int networkIdToDisconnect = ssidToNetworkId(ssidToDisconnect); + int networkIdToDisconnect = ssidToNetworkId(ssidToDisconnect, authType); if (networkIdToDisconnect > 0) { @@ -1080,16 +1111,18 @@ private boolean getSSIDNetworkID(CallbackContext callbackContext, JSONArray data } String ssidToGetNetworkID = ""; + String authType = ""; try { ssidToGetNetworkID = data.getString(0); + authType = data.getString(1); } catch (Exception e) { callbackContext.error(e.getMessage()); Log.d(TAG, e.getMessage()); return false; } - int networkIdToConnect = ssidToNetworkId(ssidToGetNetworkID); + int networkIdToConnect = ssidToNetworkId(ssidToGetNetworkID, authType); callbackContext.success(networkIdToConnect); return true; @@ -1198,8 +1231,7 @@ private boolean isWifiEnabled(CallbackContext callbackContext) { * This method takes a given String, searches the current list of configured WiFi networks, and * returns the networkId for the network if the SSID matches. If not, it returns -1. */ - private int ssidToNetworkId(String ssid) { - + private int ssidToNetworkId(String ssid, String authType) { try { int maybeNetId = Integer.parseInt(ssid); @@ -1207,22 +1239,72 @@ private int ssidToNetworkId(String ssid) { return maybeNetId; } catch (NumberFormatException e) { - List currentNetworks = wifiManager.getConfiguredNetworks(); int networkId = -1; - - // For each network in the list, compare the SSID with the given one + // For each network in the list, compare the SSID with the given one and check if authType matches for (WifiConfiguration test : currentNetworks) { - if (test.SSID != null && test.SSID.equals(ssid)) { - networkId = test.networkId; + if (test.SSID != null) { + if (authType.length() == 0) { + if(test.SSID.equals(ssid)) { + networkId = test.networkId; + } + } else { + String testSSID = test.SSID + this.getSecurityType(test); + if(testSSID.equals(ssid + authType)) { + networkId = test.networkId; + } + } + } + } + // Fallback to WPA if WPA2 is not found + if (networkId == -1 && authType.substring(0,3).equals("WPA")) { + for (WifiConfiguration test : currentNetworks) { + if (test.SSID != null) { + if (authType.length() == 0) { + if(test.SSID.equals(ssid)) { + networkId = test.networkId; + } + } else { + String testSSID = test.SSID + this.getSecurityType(test).substring(0,3); + if(testSSID.equals(ssid + authType)) { + networkId = test.networkId; + } + } + } } } - return networkId; - } } + // Get the different configured security types + static public String getSecurityType(WifiConfiguration wifiConfig) { + + if (wifiConfig.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE)) { + // If we never set group ciphers, wpa_supplicant puts all of them. + // For open, we don't set group ciphers. + // For WEP, we specifically only set WEP40 and WEP104, so CCMP + // and TKIP should not be there. + if (!wifiConfig.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.CCMP) + && (wifiConfig.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.WEP40) + || wifiConfig.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.WEP104))) { + return "WEP"; + } else { + return "NONE"; + } + } else if (wifiConfig.allowedProtocols.get(WifiConfiguration.Protocol.RSN)) { + return "WPA2"; + } else if (wifiConfig.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP)) { + return "WPA";//"WPA_EAP"; + } else if (wifiConfig.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X)) { + return "WPA";//"IEEE8021X"; + } else if (wifiConfig.allowedProtocols.get(WifiConfiguration.Protocol.WPA)) { + return "WPA"; + } else { + Log.w(TAG, "Unknown security type from WifiConfiguration, falling back on open."); + return "NONE"; + } + } /** * This method enables or disables the wifi */ diff --git a/src/ios/WifiWizard2.h b/src/ios/WifiWizard2.h index 3f2ab83..38b61b9 100644 --- a/src/ios/WifiWizard2.h +++ b/src/ios/WifiWizard2.h @@ -6,6 +6,7 @@ - (void)iOSConnectNetwork:(CDVInvokedUrlCommand *)command; - (void)iOSConnectOpenNetwork:(CDVInvokedUrlCommand *)command; - (void)iOSDisconnectNetwork:(CDVInvokedUrlCommand *)command; +- (void)getWifiIP:(CDVInvokedUrlCommand *)command; - (void)getConnectedSSID:(CDVInvokedUrlCommand *)command; - (void)getConnectedBSSID:(CDVInvokedUrlCommand *)command; - (void)isWifiEnabled:(CDVInvokedUrlCommand *)command; diff --git a/src/ios/WifiWizard2.m b/src/ios/WifiWizard2.m index 675c571..a78fcbb 100644 --- a/src/ios/WifiWizard2.m +++ b/src/ios/WifiWizard2.m @@ -1,11 +1,51 @@ #import "WifiWizard2.h" #include +#include #import #import -#import +#import +#import @implementation WifiWizard2 +- (void)getWifiIP:(CDVInvokedUrlCommand*)command { + CDVPluginResult *pluginResult = nil; + + NSString *address = @"error"; + struct ifaddrs *interfaces = NULL; + struct ifaddrs *temp_addr = NULL; + int success = 0; + // retrieve the current interfaces - returns 0 on success + success = getifaddrs(&interfaces); + if (success == 0) { + // Loop through linked list of interfaces + temp_addr = interfaces; + while(temp_addr != NULL) { + if(temp_addr->ifa_addr->sa_family == AF_INET) { + // Check if interface is en0 which is the wifi connection on the iPhone + if([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) { + // Get NSString from C String + address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)]; + + } + + } + + temp_addr = temp_addr->ifa_next; + } + } + // Free memory + freeifaddrs(interfaces); + if (address) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:address]; + } else { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Not available"]; + } + + [self.commandDelegate sendPluginResult:pluginResult + callbackId:command.callbackId]; +} + - (id)fetchSSIDInfo { // see http://stackoverflow.com/a/5198968/907720 NSArray *ifs = (__bridge_transfer NSArray *)CNCopySupportedInterfaces(); @@ -50,22 +90,31 @@ - (void)iOSConnectNetwork:(CDVInvokedUrlCommand*)command { passwordString = [options objectForKey:@"Password"]; if (@available(iOS 11.0, *)) { - if (ssidString && [ssidString length]) { - NEHotspotConfiguration *configuration = [[NEHotspotConfiguration - alloc] initWithSSID:ssidString - passphrase:passwordString - isWEP:(BOOL)false]; - - configuration.joinOnce = false; - + if (ssidString && [ssidString length]) { + NEHotspotConfiguration *configuration; + + + if (@available(iOS 13.0, *)) { + configuration = [[NEHotspotConfiguration + alloc] initWithSSIDPrefix:ssidString + passphrase:passwordString + isWEP:(BOOL)false]; + } else { + configuration = [[NEHotspotConfiguration + alloc] initWithSSID:ssidString + passphrase:passwordString + isWEP:(BOOL)false]; + } + configuration.joinOnce = false; + [[NEHotspotConfigurationManager sharedManager] applyConfiguration:configuration completionHandler:^(NSError * _Nullable error) { NSDictionary *r = [self fetchSSIDInfo]; NSString *ssid = [r objectForKey:(id)kCNNetworkInfoKeySSID]; //@"SSID" - if ([ssid isEqualToString:ssidString]){ - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:ssidString]; + if ([ssid hasPrefix:ssidString]){ + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:ssid]; }else{ pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:error.description]; } @@ -73,7 +122,6 @@ - (void)iOSConnectNetwork:(CDVInvokedUrlCommand*)command { callbackId:command.callbackId]; }]; - } else { pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"SSID Not provided"]; [self.commandDelegate sendPluginResult:pluginResult @@ -100,8 +148,16 @@ - (void)iOSConnectOpenNetwork:(CDVInvokedUrlCommand*)command { if (@available(iOS 11.0, *)) { if (ssidString && [ssidString length]) { - NEHotspotConfiguration *configuration = [[NEHotspotConfiguration - alloc] initWithSSID:ssidString]; + NEHotspotConfiguration *configuration; + + + if (@available(iOS 13.0, *)) { + configuration = [[NEHotspotConfiguration + alloc] initWithSSIDPrefix:ssidString]; + } else { + configuration = [[NEHotspotConfiguration + alloc] initWithSSID:ssidString]; + } configuration.joinOnce = false; @@ -111,8 +167,8 @@ - (void)iOSConnectOpenNetwork:(CDVInvokedUrlCommand*)command { NSString *ssid = [r objectForKey:(id)kCNNetworkInfoKeySSID]; //@"SSID" - if ([ssid isEqualToString:ssidString]){ - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:ssidString]; + if ([ssid hasPrefix:ssidString]){ + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:ssid]; }else{ pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:error.description]; } @@ -161,9 +217,8 @@ - (void)iOSDisconnectNetwork:(CDVInvokedUrlCommand*)command { - (void)getConnectedSSID:(CDVInvokedUrlCommand*)command { CDVPluginResult *pluginResult = nil; - NSDictionary *r = [self fetchSSIDInfo]; - NSString *ssid = [r objectForKey:(id)kCNNetworkInfoKeySSID]; //@"SSID" + NSString *ssid = [self getWifiSsid]; //@"SSID" if (ssid && [ssid length]) { pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:ssid]; @@ -329,5 +384,41 @@ - (void)canConnectToRouter:(CDVInvokedUrlCommand*)command { callbackId:command.callbackId]; } +- (NSString*) getWifiSsid { + if (@available(iOS 13.0, *)) { + if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied) { + NSLog(@"User has explicitly denied authorization for this application, or location services are disabled in Settings."); + //[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]]; + return nil; + } + CLLocationManager* cllocation = [[CLLocationManager alloc] init]; + if(![CLLocationManager locationServicesEnabled] || [CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined){ + [cllocation requestWhenInUseAuthorization]; + usleep(500); + return [self getWifiSsid]; + } + } + NSString *wifiName = nil; + CFArrayRef wifiInterfaces = CNCopySupportedInterfaces(); + if (!wifiInterfaces) { + return nil; + } + NSArray *interfaces = (__bridge NSArray *)wifiInterfaces; + for (NSString *interfaceName in interfaces) { + CFDictionaryRef dictRef = CNCopyCurrentNetworkInfo((__bridge CFStringRef)(interfaceName)); + + if (dictRef) { + NSDictionary *networkInfo = (__bridge NSDictionary *)dictRef; + NSLog(@"network info -> %@", networkInfo); + wifiName = [networkInfo objectForKey:(__bridge NSString *)kCNNetworkInfoKeySSID]; + CFRelease(dictRef); + } + } + + CFRelease(wifiInterfaces); + return wifiName; +} + + @end diff --git a/www/WifiWizard2.js b/www/WifiWizard2.js index e6460ce..b670484 100644 --- a/www/WifiWizard2.js +++ b/www/WifiWizard2.js @@ -8,7 +8,7 @@ * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express oWPA2r implied. * See the License for the specific language governing permissions and * limitations under the License. */ @@ -86,6 +86,10 @@ var WifiWizard2 = { if (typeof wifi.auth == "object") { switch (wifi.auth.algorithm) { + case "WPA2": + networkInformation.push("WPA2"); + networkInformation.push(wifi.auth.password); + break; case "WPA": networkInformation.push("WPA"); networkInformation.push(wifi.auth.password); @@ -123,11 +127,12 @@ var WifiWizard2 = { /** * Remove wifi network configuration * @param {string|int} [SSID] + * @param {string} [algorithm] * @returns {Promise} */ - remove: function (SSID) { + remove: function (SSID, algorithm) { return new Promise(function (resolve, reject) { - cordova.exec(resolve, reject, "WifiWizard2", "remove", [WifiWizard2.formatWifiString(SSID)]); + cordova.exec(resolve, reject, "WifiWizard2", "remove", [WifiWizard2.formatWifiString(SSID), algorithm || ""]); }); }, @@ -161,7 +166,7 @@ var WifiWizard2 = { WifiWizard2.add(wifiConfig).then(function (newNetID) { // Successfully updated or added wifiConfig - cordova.exec(resolve, reject, "WifiWizard2", "connect", [WifiWizard2.formatWifiString(SSID), bindAll]); + cordova.exec(resolve, reject, "WifiWizard2", "connect", [WifiWizard2.formatWifiString(SSID), bindAll, wifiConfig.auth.algorithm || ""]); // Catch error adding/updating network }).catch(function (error) { @@ -172,7 +177,7 @@ var WifiWizard2 = { // This error above should only be returned when the add method was able to pull a network ID (as it tries to update instead of adding) // Lets go ahead and attempt to connect to that SSID (using the existing wifi configuration) - cordova.exec(resolve, reject, "WifiWizard2", "connect", [WifiWizard2.formatWifiString(SSID), bindAll]); + cordova.exec(resolve, reject, "WifiWizard2", "connect", [WifiWizard2.formatWifiString(SSID), bindAll, wifiConfig.auth.algorithm || ""]); } else { @@ -192,13 +197,14 @@ var WifiWizard2 = { * call WifiWizard2.disable() instead of disconnect. * * @param {string|int} [SSID=all] + * @param {string} [algorithm] * @returns {Promise} */ - disconnect: function (SSID) { + disconnect: function (SSID, algorithm) { return new Promise(function (resolve, reject) { if (SSID) { - cordova.exec(resolve, reject, "WifiWizard2", "disconnectNetwork", [WifiWizard2.formatWifiString(SSID)]); + cordova.exec(resolve, reject, "WifiWizard2", "disconnectNetwork", [WifiWizard2.formatWifiString(SSID), algorithm || ""]); } else { cordova.exec(resolve, reject, "WifiWizard2", "disconnect", []); } @@ -211,24 +217,26 @@ var WifiWizard2 = { * @param {string|int} [SSID] * @param {boolean} [bindAll=false] Whether or not to bind all network requests to this wifi network * @param {boolean} [waitForConnection=false] Whether or not to wait before resolving promise until connection to wifi is verified + * @param {string} [algorithm] * @returns {Promise} */ - enable: function (SSID, bindAll, waitForConnection) { + enable: function (SSID, bindAll, waitForConnection, algorithm) { return new Promise(function (resolve, reject) { bindAll = bindAll ? true : false; waitForConnection = waitForConnection ? true : false; - cordova.exec(resolve, reject, "WifiWizard2", "enable", [WifiWizard2.formatWifiString(SSID), bindAll, waitForConnection]); + cordova.exec(resolve, reject, "WifiWizard2", "enable", [WifiWizard2.formatWifiString(SSID), bindAll, waitForConnection, algorithm || ""]); }); }, /** * Disable Network * @param {string|int} [SSID] + * @param {string} [algorithm] * @returns {Promise} */ - disable: function (SSID) { + disable: function (SSID, algorithm) { return new Promise(function (resolve, reject) { - cordova.exec(resolve, reject, "WifiWizard2", "disable", [WifiWizard2.formatWifiString(SSID)]); + cordova.exec(resolve, reject, "WifiWizard2", "disable", [WifiWizard2.formatWifiString(SSID), algorithm || ""]); }); }, @@ -395,11 +403,12 @@ var WifiWizard2 = { /** * Get Network ID from SSID * @param {string|int} [SSID] + * @param {string} [algorithm] * @returns {Promise} */ - getSSIDNetworkID: function (SSID) { + getSSIDNetworkID: function (SSID, algorithm) { return new Promise(function (resolve, reject) { - cordova.exec(resolve, reject, "WifiWizard2", "getSSIDNetworkID", [WifiWizard2.formatWifiString(SSID)]); + cordova.exec(resolve, reject, "WifiWizard2", "getSSIDNetworkID", [WifiWizard2.formatWifiString(SSID), algorithm || ""]); }); }, @@ -562,6 +571,12 @@ var WifiWizard2 = { wifiConfig.auth = { algorithm: "NONE" }; + } else if (algorithm === "WPA2") { + wifiConfig.auth = { + algorithm: algorithm, + password: WifiWizard2.formatWifiString(password) + // Other parameters can be added depending on algorithm. + }; } else if (algorithm === "WPA") { wifiConfig.auth = { algorithm: algorithm,