WifiChecker.java
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  * Copyright (c) 2011, Willow Garage, Inc.
00005  *
00006  * All rights reserved.
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions
00009  * are met:
00010  *
00011  *  * Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  *  * Redistributions in binary form must reproduce the above
00014  *    copyright notice, this list of conditions and the following
00015  *    disclaimer in the documentation and/or other materials provided
00016  *    with the distribution.
00017  *  * Neither the name of Willow Garage, Inc. nor the names of its
00018  *    contributors may be used to endorse or promote products derived
00019  *    from this software without specific prior written permission.
00020  *
00021  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  * POSSIBILITY OF SUCH DAMAGE.
00033  */
00034 
00035 package com.github.rosjava.android_remocons.common_tools.system;
00036 
00037 import android.net.wifi.ScanResult;
00038 import android.net.wifi.SupplicantState;
00039 import android.net.wifi.WifiConfiguration;
00040 import android.net.wifi.WifiInfo;
00041 import android.net.wifi.WifiManager;
00042 import android.util.Log;
00043 
00044 import com.github.rosjava.android_remocons.common_tools.master.MasterId;
00045 
00046 import java.util.List;
00047 
00053 public class WifiChecker {
00054     public interface SuccessHandler {
00058         void handleSuccess();
00059     }
00060 
00061     public interface FailureHandler {
00066         void handleFailure(String reason);
00067     }
00068 
00069     public interface ReconnectionHandler {
00073         boolean doReconnection(String from, String to);
00074     }
00075 
00076     private CheckerThread checkerThread;
00077     private SuccessHandler foundWiFiCallback;
00078     private FailureHandler failureCallback;
00079     private ReconnectionHandler reconnectionCallback;
00080 
00084     public WifiChecker(SuccessHandler foundWiFiCallback, FailureHandler failureCallback, ReconnectionHandler reconnectionCallback) {
00085         this.foundWiFiCallback = foundWiFiCallback;
00086         this.failureCallback = failureCallback;
00087         this.reconnectionCallback = reconnectionCallback;
00088     }
00089 
00094     public void beginChecking(MasterId masterId, WifiManager manager) {
00095         stopChecking();
00096         //If there's no wifi tag in the master id, skip this step
00097         if (masterId.getWifi() == null) {
00098             foundWiFiCallback.handleSuccess();
00099             return;
00100         }
00101         checkerThread = new CheckerThread(masterId, manager);
00102         checkerThread.start();
00103     }
00104 
00108     public void stopChecking() {
00109         if (checkerThread != null && checkerThread.isAlive()) {
00110             checkerThread.interrupt();
00111         }
00112     }
00113 
00114     public static boolean wifiValid(MasterId masterId, WifiManager wifiManager) {
00115         WifiInfo wifiInfo = wifiManager.getConnectionInfo();
00116         if (masterId.getWifi() == null) { //Does not matter what wifi network, always valid.
00117             return true;
00118         }
00119         if (wifiManager.isWifiEnabled()) {
00120             if (wifiInfo != null) {
00121                 Log.d("WiFiChecker", "WiFi Info: " + wifiInfo.toString() + " IP " + wifiInfo.getIpAddress());
00122                 if (wifiInfo.getSSID() != null && wifiInfo.getIpAddress() != 0
00123                         && wifiInfo.getSupplicantState() == SupplicantState.COMPLETED) {
00124                     String master_SSID = "\"" + masterId.getWifi() + "\"";
00125                     if (wifiInfo.getSSID().equals(master_SSID)) {
00126                         return true;
00127                     }
00128                 }
00129             }
00130         }
00131         return false;
00132     }
00133 
00134     public String getScanResultSecurity(ScanResult scanResult) {
00135         final String cap = scanResult.capabilities;
00136         final String[] securityModes = { "WEP", "PSK", "EAP" };
00137         for (int i = securityModes.length - 1; i >= 0; i--) {
00138             if (cap.contains(securityModes[i])) {
00139                 return securityModes[i];
00140             }
00141         }
00142         return "OPEN";
00143     }
00144 
00145     private class CheckerThread extends Thread {
00146         private MasterId masterId;
00147         private WifiManager wifiManager;
00148 
00149         public CheckerThread(MasterId masterId, WifiManager wifi) {
00150             this.masterId = masterId;
00151             this.wifiManager = wifi;
00152             setDaemon(true);
00153             // don't require callers to explicitly kill all the old checker threads.
00154             setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
00155                 @Override
00156                 public void uncaughtException(Thread thread, Throwable ex) {
00157                     failureCallback.handleFailure("exception: " + ex.getMessage());
00158                 }
00159             });
00160         }
00161 
00162         private boolean wifiValid() {
00163             return WifiChecker.wifiValid(masterId, wifiManager);
00164         }
00165 
00166         @Override
00167         public void run() {
00168             try {
00169                 if (wifiValid()) {
00170                     foundWiFiCallback.handleSuccess();
00171                 } else if (reconnectionCallback.doReconnection(wifiManager.getConnectionInfo().getSSID(), masterId.getWifi())) {
00172                     Log.d("WiFiChecker", "Wait for networking");
00173                     wifiManager.setWifiEnabled(true);
00174                     int i = 0;
00175                     while (i < 30 && !wifiManager.isWifiEnabled()) {
00176                         Log.d("WiFiChecker", "Waiting for WiFi enable");
00177                         Thread.sleep(1000L);
00178                         i++;
00179                     }
00180                     if (!wifiManager.isWifiEnabled()) {
00181                         failureCallback.handleFailure("Un-able to enable to WiFi");
00182                         return;
00183                     }
00184                     int n = -1;
00185                     int priority = -1;
00186                     WifiConfiguration wc = null;
00187                     String SSID = "\"" + masterId.getWifi() + "\"";
00188                     for (WifiConfiguration test : wifiManager.getConfiguredNetworks()) {
00189                         Log.d("WiFiChecker", "WIFI " + test.toString());
00190                         if (test.priority > priority) {
00191                             priority = test.priority;
00192                         }
00193                         if (test.SSID.equals(SSID)) {
00194                             n = test.networkId;
00195                             wc = test;
00196                         }
00197                     }
00198                     if (wc != null) {
00199                         if (wc.priority != priority) {
00200                             wc.priority = priority + 1;
00201                         }
00202                         wc.status = WifiConfiguration.Status.DISABLED;
00203                         wifiManager.updateNetwork(wc);
00204                     }
00205 
00206                     //Add new network.
00207                     if (n == -1) {
00208                         Log.d("WiFiChecker", "WIFI Unknown");
00209 
00210                         List<ScanResult> scanResultList = null;
00211                         Log.d("WiFiChecker", "WIFI Scan Start");
00212                         if(wifiManager.startScan()){
00213                             Log.d("WiFiChecker", "WIFI Scan Success");
00214                         }
00215                         else{
00216                             Log.d("WiFiChecker", "WIFI Scan Failure");
00217                             failureCallback.handleFailure("wifi scan fail");
00218                         }
00219 
00220                         scanResultList = wifiManager.getScanResults();
00221                         i = 0;
00222                         while (i < 30 && scanResultList.size()==0) {
00223                             scanResultList = wifiManager.getScanResults();
00224                             Log.d("WiFiChecker", "Waiting for getting wifi list");
00225                             Thread.sleep(1000L);
00226                             i++;
00227                         }
00228                         wc = new WifiConfiguration();
00229 
00230                         for (ScanResult result : scanResultList) {
00231 
00232                             if (result.SSID.equals(masterId.getWifi())) {
00233                                 String securityMode = getScanResultSecurity(result);
00234                                 Log.d("WiFiChecker", "WIFI mode: " + securityMode);
00235 
00236                                 wc.SSID = "\"" + masterId.getWifi() + "\"";
00237                                 if (securityMode.equalsIgnoreCase("OPEN")) {
00238                                     wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
00239                                 } else if (securityMode.equalsIgnoreCase("WEP")) {
00240                                     wc.wepKeys[0] = "\"" + masterId.getWifiPassword() + "\"";
00241                                     wc.wepTxKeyIndex = 0;
00242                                     wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
00243                                     wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
00244                                 } else {
00245                                     wc.preSharedKey = "\"" + masterId.getWifiPassword() + "\"";
00246                                     wc.hiddenSSID = true;
00247                                     wc.status = WifiConfiguration.Status.ENABLED;
00248                                     wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
00249                                     wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
00250                                     wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
00251                                     wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
00252                                     wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
00253                                     wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
00254                                     wc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
00255                                 }
00256                                 n = wifiManager.addNetwork(wc);
00257                                 break;
00258 
00259                             }
00260                         }
00261                     }
00262                     Log.d("WiFiChecker", "add Network returned " + n);
00263                     if (n == -1) {
00264                         failureCallback.handleFailure("Failed to add the WiFi configure");
00265                     }
00266 
00267                     //Connect to the network
00268                     boolean b = wifiManager.enableNetwork(n, true);
00269                     Log.d("WiFiChecker", "enableNetwork returned " + b);
00270                     if (b) {
00271                         wifiManager.reconnect();
00272                         Log.d("WiFiChecker", "Wait for wifi network");
00273                         i = 0;
00274                         while (i < 3 && !wifiValid()) {
00275                             Log.d("WiFiChecker", "Waiting for network: " + i + " " + wifiManager.getWifiState());
00276                             Thread.sleep(3000L);
00277                             i++;
00278                         }
00279                         if (wifiValid()) {
00280                             foundWiFiCallback.handleSuccess();
00281                         } else {
00282                             failureCallback.handleFailure("WiFi connection timed out");
00283                         }
00284                     }
00285                 } else {
00286                     failureCallback.handleFailure("Wrong WiFi network");
00287                 }
00288             } catch (Throwable ex) {
00289                 Log.e("RosAndroid", "Exception while searching for WiFi for "
00290                         + masterId.getWifi(), ex);
00291                 failureCallback.handleFailure(ex.toString());
00292             }
00293         }
00294     }
00295 }


android_remocons
Author(s): Daniel Stonier, Kazuto Murase
autogenerated on Sat Jun 8 2019 19:32:24