Initial commit

This commit is contained in:
2018-09-22 10:44:38 +08:00
commit eacb95c18a
723 changed files with 100993 additions and 0 deletions
@@ -0,0 +1,177 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
@@ -0,0 +1,153 @@
# WifiWizard
Version 0.2.10
`getCurrentBSSID` now available on IOS.
Fixed callback issue with `connectNetwork`. It now checks to make sure you are connected to the specific network before returning.
Updated permissions for Android Marshmallow.
Version 0.2.9
This Phonegap plugin enables WiFi management from within Phonegap applications.
iOS has limited functionality, as Apple's WifiManager equivalent is only available as a private API. Any app that used these features would not be allowed on the app store. The only function availabe for iOS is `getCurrentSSID`.
### Installation
#### Master
Run `phonegap plugin install https://github.com/parsonsmatt/WifiWizard.git`. Please note that the plugin is in active development, and this will pull the most recent commits.
#### Releases
Run `cordova plugin add com.pylonproducts.wifiwizard`. This will get the latest release of the plugin.
### Usage from within Cordova/Phonegap:
#### `WifiWizard.formatWifiConfig(SSID, password, algorithm);`
Formats the wifi configuration information into a JSON for use with the addNetwork function. Currently, only WPA is supported for the `algorithm` value.
#### `WifiWizard.formatWPAConfig(SSID, password);`
Is a helper method. It returns an object which can be used to add a WPA wifi network.
#### `WifiWizard.addNetwork(wifi, win, fail);`
Adds the network to the list of available networks that the user can log into. `wifi` needs to be an object as formatted by formatWifiConfig. `win` and `fail` are callback functions to be executed based on the result of the call.
#### `WifiWizard.removeNetwork(SSID, win, fail);`
Removes the network with the given SSID. As above, `win` and `fail` are callback functions.
#### `WifiWizard.connectNetwork(SSID, win, fail);`
Connects the phone to the given Wifi network.
#### `WifiWizard.disconnectNetwork(SSID, win, fail);`
Disconnects the phone to the given Wifi network.
#### `WifiWizard.listNetworks(listHandler, fail);`
Retrieves a list of the configured networks as an array of strings and passes them to the function listHandler.
#### `WifiWizard.startScan(success, fail);`
Start WiFi scanning. `success` is a function that is called when the scan is started.
#### `WifiWizard.getScanResults([options], listHandler, fail);`
Retrieves a list of the available networks as an array of objects and passes them to the function listHandler. The format of the array is:
networks = [
{ "level": signal_level, // raw RSSI value
"SSID": ssid, // SSID as string, with escaped double quotes: "\"ssid name\""
"BSSID": bssid // MAC address of WiFi router as string
"frequency": frequency of the access point channel in MHz
"capabilities": capabilities // Describes the authentication, key management, and encryption schemes supported by the access point.
"timestamp": timestamp in microseconds (since boot) when this result was last seen.
}
]
An options object may be passed. Currently, the only supported option is `numLevels`, and it has the following behavior:
- if `(n == true || n < 2)`, `*.getScanResults({numLevels: n})` will return data as before, split in 5 levels;
- if `(n > 1)`, `*.getScanResults({numLevels: n})` will calculate the signal level, split in n levels;
- if `(n == false)`, `*.getScanResults({numLevels: n})` will use the raw signal level;
#### `WifiWizard.getCurrentSSID(ssidHandler, fail);`
Retrieves the current SSID and passes it to ssidHandler.
#### `WifiWizard.isWifiEnabled(win, fail);`
Retrieves the current wifi status and passes `true` or `false` to the handler.
#### `WifiWizard.setWifiEnabled(enabled, win, fail);`
Set wifi status. `enabled` is a Boolean type, so to disable the Wifi, you'd execute `WifiWizard.setWifiEnabled(false, win, fail);`
### Changelog:
#### v0.2.9
`isWifiEnabled` bug fixed. `level` in `getScanResults` object now refers to raw RSSI value. The function now accepts an options object, and by specifiying `{ numLevels: value }` you can get the old behavior.
#### v0.2.8
`getScanResults` now returns the BSSID along with the SSID and strength of the network.
#### v0.2.7
- Clobber WifiWizard.js automatically via Cordova plugin architecture
#### v0.2.6
- Added `isWifiEnabled`, `setWifiEnabled`
#### v0.2.5
- Fixes `getConnectedSSID` error handlers
#### v0.2.4
- Added `getConnectedSSID` method
#### v0.2.3
- Added `disconnect` that does disconnection on current WiFi
#### v0.2.2
- Added `startScan` and `getScanResults`
#### v0.2.1
- Fixed reference problem in `formatWPAConfig`
#### v0.2.0
- Changed format of wifiConfiguration object to allow more extensibility.
#### v0.1.1
- `addNetwork` will now update the network if the SSID already exists.
#### v0.1.0
- All functions now work!
#### v0.0.3
- Fixed errors in native implementation. Currently, Add and Remove networks aren't working, but others are working as expected.
#### v0.0.2
- Changed plugin.xml and WifiWizard.js to attach WifiWizard directly to the HTML.
#### v0.0.1
- Initial commit
@@ -0,0 +1,100 @@
{
"_args": [
[
{
"raw": "wifiwizard",
"scope": null,
"escapedName": "wifiwizard",
"name": "wifiwizard",
"rawSpec": "",
"spec": "latest",
"type": "tag"
},
"D:\\pWork\\yunkong2.vis.cordova\\node_modules"
]
],
"_from": "wifiwizard@latest",
"_id": "wifiwizard@0.2.11",
"_inCache": true,
"_location": "/wifiwizard",
"_nodeVersion": "0.12.7",
"_npmUser": {
"name": "hoerresb",
"email": "brandonhoerres@gmail.com"
},
"_npmVersion": "2.11.3",
"_phantomChildren": {},
"_requested": {
"raw": "wifiwizard",
"scope": null,
"escapedName": "wifiwizard",
"name": "wifiwizard",
"rawSpec": "",
"spec": "latest",
"type": "tag"
},
"_requiredBy": [
"#USER",
"/"
],
"_resolved": "https://registry.npmjs.org/wifiwizard/-/wifiwizard-0.2.11.tgz",
"_shasum": "ed2db47bc4ac621c12de1d6ef5948822e964df14",
"_shrinkwrap": null,
"_spec": "wifiwizard",
"_where": "D:\\pWork\\yunkong2.vis.cordova\\node_modules",
"author": {
"name": "Matt Parsons"
},
"bugs": {
"url": "https://github.com/parsonsmatt/wifiwizard/issues"
},
"cordova": {
"id": "com.pylonproducts.wifiwizard",
"platforms": [
"android",
"ios"
]
},
"dependencies": {},
"description": "This plugin allows Phonegap applications to manage Wifi connections.",
"devDependencies": {},
"directories": {},
"dist": {
"shasum": "ed2db47bc4ac621c12de1d6ef5948822e964df14",
"tarball": "https://registry.npmjs.org/wifiwizard/-/wifiwizard-0.2.11.tgz"
},
"gitHead": "6a7701ebe2ec7e7bb176c63375d0c67a3de87972",
"homepage": "https://github.com/parsonsmatt/wifiwizard#readme",
"keywords": [
"phonegap",
"network",
"wifi",
"ecosystem:cordova",
"cordova-android",
"cordova-ios"
],
"license": "Apache 2.0",
"maintainers": [
{
"name": "asmund1",
"email": "asmund@herikstad.net"
},
{
"name": "hoerresb",
"email": "brandonhoerres@gmail.com"
},
{
"name": "parsonsmatt",
"email": "parsonsmatt@gmail.com"
}
],
"name": "wifiwizard",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+https://github.com/parsonsmatt/wifiwizard.git"
},
"scripts": {},
"version": "0.2.11"
}
@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
xmlns:android="http://schemas.android.com/apk/res/android"
id="com.pylonproducts.wifiwizard"
version="0.2.11">
<name>WifiWizard</name>
<description>This plugin allows Phonegap applications to manage Wifi connections.</description>
<author>Matt Parsons</author>
<keywords>phonegap,network,wifi</keywords>
<license>Apache 2.0</license>
<repo>https://github.com/parsonsmatt/WifiWizard/</repo>
<js-module src="www/WifiWizard.js" name="WifiWizard">
<clobbers target="window.WifiWizard"/>
</js-module>
<platform name="android">
<config-file target="AndroidManifest.xml" parent="/manifest">
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
</config-file>
<config-file target="res/xml/config.xml" parent="/*">
<feature name="WifiWizard">
<param name="android-package" value="com.pylonproducts.wifiwizard.WifiWizard" />
<param name="onload" value="true" />
</feature>
</config-file>
<source-file src="src/android/src/com/pylonproducts/wifiwizard/WifiWizard.java" target-dir="src/com/pylonproducts/wifiwizard" />
</platform>
<platform name="ios">
<config-file target="config.xml" parent="/*">
<feature name="WifiWizard">
<param name="ios-package" value="NXWWifiWizard"/>
</feature>
</config-file>
<header-file src="src/ios/NXWWifiWizard.h"/>
<source-file src="src/ios/NXWWifiWizard.m"/>
<framework src="SystemConfiguration.framework" />
</platform>
</plugin>
@@ -0,0 +1,570 @@
/*
* Copyright 2015 Matt Parsons
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.pylonproducts.wifiwizard;
import org.apache.cordova.*;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiInfo;
import android.net.wifi.SupplicantState;
import android.content.Context;
import android.util.Log;
public class WifiWizard extends CordovaPlugin {
private static final String ADD_NETWORK = "addNetwork";
private static final String REMOVE_NETWORK = "removeNetwork";
private static final String CONNECT_NETWORK = "connectNetwork";
private static final String DISCONNECT_NETWORK = "disconnectNetwork";
private static final String DISCONNECT = "disconnect";
private static final String LIST_NETWORKS = "listNetworks";
private static final String START_SCAN = "startScan";
private static final String GET_SCAN_RESULTS = "getScanResults";
private static final String GET_CONNECTED_SSID = "getConnectedSSID";
private static final String IS_WIFI_ENABLED = "isWifiEnabled";
private static final String SET_WIFI_ENABLED = "setWifiEnabled";
private static final String TAG = "WifiWizard";
private WifiManager wifiManager;
private CallbackContext callbackContext;
@Override
public void initialize(CordovaInterface cordova, CordovaWebView webView) {
super.initialize(cordova, webView);
this.wifiManager = (WifiManager) cordova.getActivity().getSystemService(Context.WIFI_SERVICE);
}
@Override
public boolean execute(String action, JSONArray data, CallbackContext callbackContext)
throws JSONException {
this.callbackContext = callbackContext;
if(action.equals(IS_WIFI_ENABLED)) {
return this.isWifiEnabled(callbackContext);
}
else if(action.equals(SET_WIFI_ENABLED)) {
return this.setWifiEnabled(callbackContext, data);
}
else if (!wifiManager.isWifiEnabled()) {
callbackContext.error("Wifi is not enabled.");
return false;
}
else if(action.equals(ADD_NETWORK)) {
return this.addNetwork(callbackContext, data);
}
else if(action.equals(REMOVE_NETWORK)) {
return this.removeNetwork(callbackContext, data);
}
else if(action.equals(CONNECT_NETWORK)) {
return this.connectNetwork(callbackContext, data);
}
else if(action.equals(DISCONNECT_NETWORK)) {
return this.disconnectNetwork(callbackContext, data);
}
else if(action.equals(LIST_NETWORKS)) {
return this.listNetworks(callbackContext);
}
else if(action.equals(START_SCAN)) {
return this.startScan(callbackContext);
}
else if(action.equals(GET_SCAN_RESULTS)) {
return this.getScanResults(callbackContext, data);
}
else if(action.equals(DISCONNECT)) {
return this.disconnect(callbackContext);
}
else if(action.equals(GET_CONNECTED_SSID)) {
return this.getConnectedSSID(callbackContext);
}
else {
callbackContext.error("Incorrect action parameter: " + action);
}
return false;
}
/**
* This methods adds a network to the list of available WiFi networks.
* If the network already exists, then it updates it.
*
* @params callbackContext A Cordova callback context.
* @params data JSON Array with [0] == SSID, [1] == password
* @return true if add successful, false if add fails
*/
private boolean addNetwork(CallbackContext callbackContext, JSONArray data) {
// Initialize the WifiConfiguration object
WifiConfiguration wifi = new WifiConfiguration();
Log.d(TAG, "WifiWizard: addNetwork entered.");
try {
// data's order for ANY object is 0: ssid, 1: authentication algorithm,
// 2+: authentication information.
String authType = data.getString(1);
if (authType.equals("WPA")) {
// WPA Data format:
// 0: ssid
// 1: auth
// 2: password
String newSSID = data.getString(0);
wifi.SSID = newSSID;
String newPass = data.getString(2);
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.RSN);
wifi.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
wifi.networkId = ssidToNetworkId(newSSID);
if ( wifi.networkId == -1 ) {
wifiManager.addNetwork(wifi);
callbackContext.success(newSSID + " successfully added.");
}
else {
wifiManager.updateNetwork(wifi);
callbackContext.success(newSSID + " successfully updated.");
}
wifiManager.saveConfiguration();
return true;
}
else if (authType.equals("WEP")) {
// TODO: connect/configure for WEP
Log.d(TAG, "WEP unsupported.");
callbackContext.error("WEP unsupported");
return false;
}
else if (authType.equals("NONE")) {
String newSSID = data.getString(0);
wifi.SSID = newSSID;
wifi.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
wifi.networkId = ssidToNetworkId(newSSID);
if ( wifi.networkId == -1 ) {
wifiManager.addNetwork(wifi);
callbackContext.success(newSSID + " successfully added.");
}
else {
wifiManager.updateNetwork(wifi);
callbackContext.success(newSSID + " successfully updated.");
}
wifiManager.saveConfiguration();
return true;
}
// TODO: Add more authentications as necessary
else {
Log.d(TAG, "Wifi Authentication Type Not Supported.");
callbackContext.error("Wifi Authentication Type Not Supported: " + authType);
return false;
}
}
catch (Exception e) {
callbackContext.error(e.getMessage());
Log.d(TAG,e.getMessage());
return false;
}
}
/**
* This method removes a network from the list of configured networks.
*
* @param callbackContext A Cordova callback context
* @param data JSON Array, with [0] being SSID to remove
* @return true if network removed, false if failed
*/
private boolean removeNetwork(CallbackContext callbackContext, JSONArray data) {
Log.d(TAG, "WifiWizard: removeNetwork entered.");
if(!validateData(data)) {
callbackContext.error("WifiWizard: removeNetwork data invalid");
Log.d(TAG, "WifiWizard: removeNetwork data invalid");
return false;
}
// TODO: Verify the type of data!
try {
String ssidToDisconnect = data.getString(0);
int networkIdToRemove = ssidToNetworkId(ssidToDisconnect);
if (networkIdToRemove >= 0) {
wifiManager.removeNetwork(networkIdToRemove);
wifiManager.saveConfiguration();
callbackContext.success("Network removed.");
return true;
}
else {
callbackContext.error("Network not found.");
Log.d(TAG, "WifiWizard: Network not found, can't remove.");
return false;
}
}
catch (Exception e) {
callbackContext.error(e.getMessage());
Log.d(TAG, e.getMessage());
return false;
}
}
/**
* This method connects a network.
*
* @param callbackContext A Cordova callback context
* @param data JSON Array, with [0] being SSID to connect
* @return true if network connected, false if failed
*/
private boolean connectNetwork(CallbackContext callbackContext, JSONArray data) {
Log.d(TAG, "WifiWizard: connectNetwork entered.");
if(!validateData(data)) {
callbackContext.error("WifiWizard: connectNetwork invalid data");
Log.d(TAG, "WifiWizard: connectNetwork invalid data.");
return false;
}
String ssidToConnect = "";
try {
ssidToConnect = data.getString(0);
}
catch (Exception e) {
callbackContext.error(e.getMessage());
Log.d(TAG, e.getMessage());
return false;
}
int networkIdToConnect = ssidToNetworkId(ssidToConnect);
if (networkIdToConnect >= 0) {
// We disable the network before connecting, because if this was the last connection before
// a disconnect(), this will not reconnect.
wifiManager.disableNetwork(networkIdToConnect);
wifiManager.enableNetwork(networkIdToConnect, true);
SupplicantState supState;
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
supState = wifiInfo.getSupplicantState();
callbackContext.success(supState.toString());
return true;
}else{
callbackContext.error("WifiWizard: cannot connect to network");
return false;
}
}
/**
* This method disconnects a network.
*
* @param callbackContext A Cordova callback context
* @param data JSON Array, with [0] being SSID to connect
* @return true if network disconnected, false if failed
*/
private boolean disconnectNetwork(CallbackContext callbackContext, JSONArray data) {
Log.d(TAG, "WifiWizard: disconnectNetwork entered.");
if(!validateData(data)) {
callbackContext.error("WifiWizard: disconnectNetwork invalid data");
Log.d(TAG, "WifiWizard: disconnectNetwork invalid data");
return false;
}
String ssidToDisconnect = "";
// TODO: Verify type of data here!
try {
ssidToDisconnect = data.getString(0);
}
catch (Exception e) {
callbackContext.error(e.getMessage());
Log.d(TAG, e.getMessage());
return false;
}
int networkIdToDisconnect = ssidToNetworkId(ssidToDisconnect);
if (networkIdToDisconnect > 0) {
wifiManager.disableNetwork(networkIdToDisconnect);
callbackContext.success("Network " + ssidToDisconnect + " disconnected!");
return true;
}
else {
callbackContext.error("Network " + ssidToDisconnect + " not found!");
Log.d(TAG, "WifiWizard: Network not found to disconnect.");
return false;
}
}
/**
* This method disconnects current network.
*
* @param callbackContext A Cordova callback context
* @return true if network disconnected, false if failed
*/
private boolean disconnect(CallbackContext callbackContext) {
Log.d(TAG, "WifiWizard: disconnect entered.");
if (wifiManager.disconnect()) {
callbackContext.success("Disconnected from current network");
return true;
} else {
callbackContext.error("Unable to disconnect from the current network");
return false;
}
}
/**
* This method uses the callbackContext.success method to send a JSONArray
* of the currently configured networks.
*
* @param callbackContext A Cordova callback context
* @param data JSON Array, with [0] being SSID to connect
* @return true if network disconnected, false if failed
*/
private boolean listNetworks(CallbackContext callbackContext) {
Log.d(TAG, "WifiWizard: listNetworks entered.");
List<WifiConfiguration> wifiList = wifiManager.getConfiguredNetworks();
JSONArray returnList = new JSONArray();
for (WifiConfiguration wifi : wifiList) {
returnList.put(wifi.SSID);
}
callbackContext.success(returnList);
return true;
}
/**
* This method uses the callbackContext.success method to send a JSONArray
* of the scanned networks.
*
* @param callbackContext A Cordova callback context
* @param data JSONArray with [0] == JSONObject
* @return true
*/
private boolean getScanResults(CallbackContext callbackContext, JSONArray data) {
List<ScanResult> scanResults = wifiManager.getScanResults();
JSONArray returnList = new JSONArray();
Integer numLevels = null;
if(!validateData(data)) {
callbackContext.error("WifiWizard: disconnectNetwork invalid data");
Log.d(TAG, "WifiWizard: disconnectNetwork invalid data");
return false;
}else if (!data.isNull(0)) {
try {
JSONObject options = data.getJSONObject(0);
if (options.has("numLevels")) {
Integer levels = options.optInt("numLevels");
if (levels > 0) {
numLevels = levels;
} else if (options.optBoolean("numLevels", false)) {
// use previous default for {numLevels: true}
numLevels = 5;
}
}
} catch (JSONException e) {
e.printStackTrace();
callbackContext.error(e.toString());
return false;
}
}
for (ScanResult scan : scanResults) {
/*
* @todo - breaking change, remove this notice when tidying new release and explain changes, e.g.:
* 0.y.z includes a breaking change to WifiWizard.getScanResults().
* Earlier versions set scans' level attributes to a number derived from wifiManager.calculateSignalLevel.
* This update returns scans' raw RSSI value as the level, per Android spec / APIs.
* If your application depends on the previous behaviour, we have added an options object that will modify behaviour:
* - if `(n == true || n < 2)`, `*.getScanResults({numLevels: n})` will return data as before, split in 5 levels;
* - if `(n > 1)`, `*.getScanResults({numLevels: n})` will calculate the signal level, split in n levels;
* - if `(n == false)`, `*.getScanResults({numLevels: n})` will use the raw signal level;
*/
int level;
if (numLevels == null) {
level = scan.level;
} else {
level = wifiManager.calculateSignalLevel(scan.level, numLevels);
}
JSONObject lvl = new JSONObject();
try {
lvl.put("level", level);
lvl.put("SSID", scan.SSID);
lvl.put("BSSID", scan.BSSID);
lvl.put("frequency", scan.frequency);
lvl.put("capabilities", scan.capabilities);
// lvl.put("timestamp", scan.timestamp);
returnList.put(lvl);
} catch (JSONException e) {
e.printStackTrace();
callbackContext.error(e.toString());
return false;
}
}
callbackContext.success(returnList);
return true;
}
/**
* This method uses the callbackContext.success method. It starts a wifi scanning
*
* @param callbackContext A Cordova callback context
* @return true if started was successful
*/
private boolean startScan(CallbackContext callbackContext) {
if (wifiManager.startScan()) {
callbackContext.success();
return true;
}
else {
callbackContext.error("Scan failed");
return false;
}
}
/**
* This method retrieves the SSID for the currently connected network
*
* @param callbackContext A Cordova callback context
* @return true if SSID found, false if not.
*/
private boolean getConnectedSSID(CallbackContext callbackContext){
if(!wifiManager.isWifiEnabled()){
callbackContext.error("Wifi is disabled");
return false;
}
WifiInfo info = wifiManager.getConnectionInfo();
if(info == null){
callbackContext.error("Unable to read wifi info");
return false;
}
String ssid = info.getSSID();
if(ssid.isEmpty()) {
ssid = info.getBSSID();
}
if(ssid.isEmpty()){
callbackContext.error("SSID is empty");
return false;
}
callbackContext.success(ssid);
return true;
}
/**
* This method retrieves the current WiFi status
*
* @param callbackContext A Cordova callback context
* @return true if WiFi is enabled, fail will be called if not.
*/
private boolean isWifiEnabled(CallbackContext callbackContext) {
boolean isEnabled = wifiManager.isWifiEnabled();
callbackContext.success(isEnabled ? "1" : "0");
return isEnabled;
}
/**
* 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) {
List<WifiConfiguration> currentNetworks = wifiManager.getConfiguredNetworks();
int networkId = -1;
// For each network in the list, compare the SSID with the given one
for (WifiConfiguration test : currentNetworks) {
if ( test.SSID.equals(ssid) ) {
networkId = test.networkId;
}
}
return networkId;
}
/**
* This method enables or disables the wifi
*/
private boolean setWifiEnabled(CallbackContext callbackContext, JSONArray data) {
if(!validateData(data)) {
callbackContext.error("WifiWizard: disconnectNetwork invalid data");
Log.d(TAG, "WifiWizard: disconnectNetwork invalid data");
return false;
}
String status = "";
try {
status = data.getString(0);
}
catch (Exception e) {
callbackContext.error(e.getMessage());
Log.d(TAG, e.getMessage());
return false;
}
if (wifiManager.setWifiEnabled(status.equals("true"))) {
callbackContext.success();
return true;
}
else {
callbackContext.error("Cannot enable wifi");
return false;
}
}
private boolean validateData(JSONArray data) {
try {
if (data == null || data.get(0) == null) {
callbackContext.error("Data is null.");
return false;
}
return true;
}
catch (Exception e) {
callbackContext.error(e.getMessage());
}
return false;
}
}
@@ -0,0 +1,18 @@
#import <Cordova/CDV.h>
@interface NXWWifiWizard : CDVPlugin
- (void)addNetwork:(CDVInvokedUrlCommand*)command;
- (void)removeNetwork:(CDVInvokedUrlCommand*)command;
- (void)connectNetwork:(CDVInvokedUrlCommand*)command;
- (void)disconnectNetwork:(CDVInvokedUrlCommand*)command;
- (void)listNetworks:(CDVInvokedUrlCommand*)command;
- (void)getScanResults:(CDVInvokedUrlCommand*)command;
- (void)startScan:(CDVInvokedUrlCommand*)command;
- (void)disconnect:(CDVInvokedUrlCommand*)command;
- (void)getConnectedSSID:(CDVInvokedUrlCommand*)command;
- (void)getConnectedBSSID:(CDVInvokedUrlCommand*)command;
- (void)isWifiEnabled:(CDVInvokedUrlCommand*)command;
- (void)setWifiEnabled:(CDVInvokedUrlCommand*)command;
@end
@@ -0,0 +1,135 @@
#import "NXWWifiWizard.h"
#import <SystemConfiguration/CaptiveNetwork.h>
@implementation NXWWifiWizard
- (id)fetchSSIDInfo {
// see http://stackoverflow.com/a/5198968/907720
NSArray *ifs = (__bridge_transfer NSArray *)CNCopySupportedInterfaces();
NSLog(@"Supported interfaces: %@", ifs);
NSDictionary *info;
for (NSString *ifnam in ifs) {
info = (__bridge_transfer NSDictionary *)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);
NSLog(@"%@ => %@", ifnam, info);
if (info && [info count]) { break; }
}
return info;
}
- (void)addNetwork:(CDVInvokedUrlCommand*)command {
CDVPluginResult *pluginResult = nil;
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Not supported"];
[self.commandDelegate sendPluginResult:pluginResult
callbackId:command.callbackId];
}
- (void)removeNetwork:(CDVInvokedUrlCommand*)command {
CDVPluginResult *pluginResult = nil;
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Not supported"];
[self.commandDelegate sendPluginResult:pluginResult
callbackId:command.callbackId];
}
- (void)connectNetwork:(CDVInvokedUrlCommand*)command {
CDVPluginResult *pluginResult = nil;
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Not supported"];
[self.commandDelegate sendPluginResult:pluginResult
callbackId:command.callbackId];
}
- (void)disconnectNetwork:(CDVInvokedUrlCommand*)command {
CDVPluginResult *pluginResult = nil;
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Not supported"];
[self.commandDelegate sendPluginResult:pluginResult
callbackId:command.callbackId];
}
- (void)listNetworks:(CDVInvokedUrlCommand*)command {
CDVPluginResult *pluginResult = nil;
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Not supported"];
[self.commandDelegate sendPluginResult:pluginResult
callbackId:command.callbackId];
}
- (void)getScanResults:(CDVInvokedUrlCommand*)command {
CDVPluginResult *pluginResult = nil;
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Not supported"];
[self.commandDelegate sendPluginResult:pluginResult
callbackId:command.callbackId];
}
- (void)startScan:(CDVInvokedUrlCommand*)command {
CDVPluginResult *pluginResult = nil;
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Not supported"];
[self.commandDelegate sendPluginResult:pluginResult
callbackId:command.callbackId];
}
- (void)disconnect:(CDVInvokedUrlCommand*)command {
CDVPluginResult *pluginResult = nil;
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Not supported"];
[self.commandDelegate sendPluginResult:pluginResult
callbackId:command.callbackId];
}
- (void)getConnectedSSID:(CDVInvokedUrlCommand*)command {
CDVPluginResult *pluginResult = nil;
NSDictionary *r = [self fetchSSIDInfo];
NSString *ssid = [r objectForKey:(id)kCNNetworkInfoKeySSID]; //@"SSID"
if (ssid && [ssid length]) {
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:ssid];
} else {
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Not available"];
}
[self.commandDelegate sendPluginResult:pluginResult
callbackId:command.callbackId];
}
- (void)getConnectedBSSID:(CDVInvokedUrlCommand*)command {
CDVPluginResult *pluginResult = nil;
NSDictionary *r = [self fetchSSIDInfo];
NSString *bssid = [r objectForKey:(id)kCNNetworkInfoKeyBSSID]; //@"SSID"
if (bssid && [bssid length]) {
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:bssid];
} else {
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Not available"];
}
[self.commandDelegate sendPluginResult:pluginResult
callbackId:command.callbackId];
}
- (void)isWifiEnabled:(CDVInvokedUrlCommand*)command {
}
- (void)setWifiEnabled:(CDVInvokedUrlCommand*)command {
CDVPluginResult *pluginResult = nil;
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Not supported"];
[self.commandDelegate sendPluginResult:pluginResult
callbackId:command.callbackId];
}
@end
@@ -0,0 +1,295 @@
/*
* Copyright 2015 Matt Parsons
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* This is the interface for the WifiWizard Phonegap plugin.
*/
var WifiWizard = {
/**
* This method formats wifi information into an object for use with the
* addNetwork function. Currently only supports
* @param SSID the SSID of the network enclosed in double quotes
* @param password the password for the network enclosed in double quotes
* @param algorithm the authentication algorithm
* @return wifiConfig a JSON object properly formatted for the plugin.
*/
formatWifiConfig: function(SSID, password, algorithm) {
var wifiConfig = {
SSID: WifiWizard.formatWifiString(SSID)
};
if (!algorithm && !password) {
// open network
wifiConfig.auth = {
algorithm: 'NONE'
};
} else if (algorithm === 'WPA') {
wifiConfig.auth = {
algorithm : algorithm,
password : WifiWizard.formatWifiString(password)
// Other parameters can be added depending on algorithm.
};
}
else if (algorithm === 'New network type') {
wifiConfig.auth = {
algorithm : algorithm
// Etc...
};
}
else {
console.log("Algorithm incorrect")
return false;
}
return wifiConfig;
},
/**
* This method is a helper method that returns a wifi object with WPA.
*/
formatWPAConfig: function(SSID, password) {
return WifiWizard.formatWifiConfig(SSID, password, 'WPA');
},
/**
* This method formats a given SSID and ensures that it is appropriate.
* If the SSID is not wrapped in double quotes, it wraps it in double quotes.
* Despite the name, this also needs to be done to WPA PSK.
* @param ssid the SSID to format
*/
formatWifiString: function(ssid) {
if (ssid === undefined || ssid === null) {
ssid = "";
}
ssid = ssid.trim()
if (ssid.charAt(0) != '"' ) {
ssid = '"' + ssid;
}
if (ssid.charAt(ssid.length-1) != '"' ) {
ssid = ssid + '"';
}
return ssid;
},
/**
* This methods adds a network to the list of available networks.
* Currently, only WPA authentication method is supported.
*
* @param wifi is JSON formatted information necessary for adding the Wifi
* network, as is done in formatWifiConfig.
* @param win is a callback function that gets called if the plugin is
* successful.
* @param fail is a callback function that gets called if the plugin gets
* an error
*/
addNetwork: function(wifi, win, fail) {
//console.log("WifiWizard add method entered.");
if (wifi !== null && typeof wifi === 'object') {
// Ok to proceed!
}
else {
console.log('WifiWizard: Invalid parameter. wifi not an object.');
}
var networkInformation = [];
if (wifi.SSID !== undefined && wifi.SSID !== '') {
networkInformation.push(wifi.SSID);
}
else {
// i dunno, like, reject the call or something? what are you even doing?
console.log('WifiWizard: No SSID given.');
return false;
}
if (typeof wifi.auth == 'object') {
switch (wifi.auth.algorithm) {
case 'WPA':
networkInformation.push('WPA');
networkInformation.push(wifi.auth.password);
break;
case 'NONE':
networkInformation.push('NONE');
break;
case 'Newly supported type':
// Push values in specific order, and implement new type in the Java code.
break;
default:
console.log("WifiWizard: authentication invalid.");
}
}
else {
console.log('WifiWizard: No authentication algorithm given.');
return false;
}
cordova.exec(win, fail, 'WifiWizard', 'addNetwork', networkInformation);
},
/**
* This method removes a given network from the list of configured networks.
* @param SSID of the network to remove
* @param win function to handle successful callback
* @param fail function to handle error callback
*/
removeNetwork: function(SSID, win, fail) {
cordova.exec(win, fail, 'WifiWizard', 'removeNetwork', [WifiWizard.formatWifiString(SSID)]);
},
/**
* This method connects a network if it is configured.
* @param SSID the network to connect
* @param win function that is called if successful
* @param fail function that is called to handle errors
*/
connectNetwork: function(SSID, win, fail) {
cordova.exec(win, fail, 'WifiWizard', 'connectNetwork', [WifiWizard.formatWifiString(SSID)]);
},
/**
* This method disconnects a network if it is configured.
* @param SSID the network to disconnect
* @param win function that is called if successful
* @param fail function that is called to handle errors
*/
disconnectNetwork: function(SSID, win, fail) {
cordova.exec(win, fail, 'WifiWizard', 'disconnectNetwork', [WifiWizard.formatWifiString(SSID)]);
},
/**
* Hands the list of previously used and configured networks to the `win` success callback function.
* @param win callback function that receives list of networks
* @param fail callback function if error
* @return a list of networks
*/
listNetworks: function(win, fail) {
if (typeof win != "function") {
console.log("listNetworks first parameter must be a function to handle list.");
return;
}
cordova.exec(win, fail, 'WifiWizard', 'listNetworks', []);
},
/**
* Hands the list of scanned networks to the `win` success callback function.
* @param opts optional json object of options
* @param win callback function that receives list of networks
* @param fail callback function if error
* @return a list of networks
*/
getScanResults: function(options, win, fail) {
if (typeof options === 'function') {
fail = win;
win = options;
options = {};
}
if (typeof win != "function") {
console.log("getScanResults first parameter must be a function to handle list.");
return;
}
cordova.exec(win, fail, 'WifiWizard', 'getScanResults', [options]);
},
/**
* Start scanning wifi.
* @param win callback function
* @param fail callback function if error
*/
startScan: function(win, fail) {
if (typeof win != "function") {
console.log("startScan first parameter must be a function to handle list.");
return;
}
cordova.exec(win, fail, 'WifiWizard', 'startScan', []);
},
/**
* Disconnect current wifi.
* @param win callback function
* @param fail callback function if error
*/
disconnect: function(win, fail) {
if (typeof win != "function") {
console.log("disconnect first parameter must be a function to handle list.");
return;
}
cordova.exec(win, fail, 'WifiWizard', 'disconnect', []);
},
/**
* Gets the currently connected wifi SSID
* @param win callback function
* @param fail callback function if error
*/
getCurrentSSID: function(win, fail) {
if (typeof win != "function") {
console.log("getCurrentSSID first parameter must be a function to handle SSID.");
return;
}
cordova.exec(win, fail, 'WifiWizard', 'getConnectedSSID', []);
},
getCurrentBSSID: function(win, fail) {
if (typeof win != "function") {
console.log("getCurrentSSID first parameter must be a function to handle SSID.");
return;
}
cordova.exec(win, fail, 'WifiWizard', 'getConnectedBSSID', []);
},
/**
* Gets 'true' or 'false' if WiFi is enabled or disabled
* @param win callback function
* @param fail
*/
isWifiEnabled: function(win, fail) {
if (typeof win != "function") {
console.log("isWifiEnabled first parameter must be a function to handle wifi status.");
return;
}
cordova.exec(
// Cordova can only return strings to JS, and the underlying plugin
// sends a "1" for true and "0" for false.
function(result) {
win(result == "1");
},
fail, 'WifiWizard', 'isWifiEnabled', []
);
},
/**
* Gets '1' if WiFi is enabled
* @param enabled callback function
* @param win callback function
* @param fail callback function if wifi is disabled
*/
setWifiEnabled: function(enabled, win, fail) {
if (typeof win != "function") {
console.log("setWifiEnabled second parameter must be a function to handle enable result.");
return;
}
cordova.exec(win, fail, 'WifiWizard', 'setWifiEnabled', [enabled]);
}
};
module.exports = WifiWizard;