WifiAutoJoinController.java revision e86c962bb99a8b126ed64ddcc6b112161549e26d
1f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle/* 262f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle * Copyright (C) 2014 The Android Open Source Project 3f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 4f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * Licensed under the Apache License, Version 2.0 (the "License"); 5f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * you may not use this file except in compliance with the License. 6f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * You may obtain a copy of the License at 7f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 8f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * http://www.apache.org/licenses/LICENSE-2.0 9f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 10f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * Unless required by applicable law or agreed to in writing, software 11f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * distributed under the License is distributed on an "AS IS" BASIS, 12f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * See the License for the specific language governing permissions and 14f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * limitations under the License. 15f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle */ 16f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 17f22d23092ab37286a5ef9d257d5bb32c421d2669vandwallepackage com.android.server.wifi; 18f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 19f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport android.content.Context; 20f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 21f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport android.net.NetworkKey; 22f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport android.net.NetworkScoreManager; 230c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalleimport android.net.WifiKey; 24f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport android.net.wifi.WifiConfiguration; 25f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport android.net.wifi.ScanResult; 26f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport android.net.wifi.WifiManager; 27f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 28f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport android.os.SystemClock; 29f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport android.util.Log; 30f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 310c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalleimport java.util.ArrayList; 320c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalleimport java.util.Collection; 33f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport java.util.Iterator; 34f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport java.util.HashMap; 35f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport java.util.List; 36f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport java.util.Date; 37f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 38f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle/** 39f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * AutoJoin controller is responsible for WiFi Connect decision 40f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 41f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * It runs in the thread context of WifiStateMachine 42f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 43f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle */ 44f22d23092ab37286a5ef9d257d5bb32c421d2669vandwallepublic class WifiAutoJoinController { 45f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 46f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private Context mContext; 47f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private WifiStateMachine mWifiStateMachine; 48f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private WifiConfigStore mWifiConfigStore; 49f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private WifiTrafficPoller mWifiTrafficPoller; 50f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private WifiNative mWifiNative; 51f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 52f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private NetworkScoreManager scoreManager; 53f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private WifiNetworkScoreCache mNetworkScoreCache; 54f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 55f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private static final String TAG = "WifiAutoJoinController "; 56ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle private static boolean DBG = false; 57ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle private static boolean VDBG = false; 58f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private static final boolean mStaStaSupported = false; 59f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private static final int SCAN_RESULT_CACHE_SIZE = 80; 60f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 61453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle private String mCurrentConfigurationKey = null; //used by autojoin 62f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 63f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private HashMap<String, ScanResult> scanResultCache = 64f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle new HashMap<String, ScanResult>(); 65f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 66f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiAutoJoinController(Context c, WifiStateMachine w, WifiConfigStore s, 67f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiTrafficPoller t, WifiNative n) { 68f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mContext = c; 69f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiStateMachine = w; 70f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiConfigStore = s; 71f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiTrafficPoller = t; 72f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiNative = n; 73f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mNetworkScoreCache = null; 74f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle scoreManager = (NetworkScoreManager) mContext.getSystemService(Context.NETWORK_SCORE_SERVICE); 75f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (scoreManager == null) 76f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("Registered scoreManager NULL " + " service " + Context.NETWORK_SCORE_SERVICE); 77f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle else 78f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("Registered scoreManager NOT NULL" + " service " + Context.NETWORK_SCORE_SERVICE); 79f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 80f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (scoreManager != null) { 81f13817203179f41620514718c8668ae7e418f8afJeff Davidson mNetworkScoreCache = new WifiNetworkScoreCache(mContext); 82f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle scoreManager.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache); 83f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else { 84f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("No network score service: Couldnt register as a WiFi score Manager, type=" 85f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.toString(NetworkKey.TYPE_WIFI) 86f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + " service " + Context.NETWORK_SCORE_SERVICE); 87f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mNetworkScoreCache = null; 88f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 89f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 90f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 91ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle void enableVerboseLogging(int verbose) { 92ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (verbose > 0 ) { 93ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle VDBG = true; 94ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } else { 95ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle VDBG = false; 96ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 97ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 98ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle 99ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle 100ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle int mScanResultMaximumAge = 30000; /* milliseconds unit */ 101f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 102ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle /* 103ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * flush out scan results older than mScanResultMaximumAge 104ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * 105ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * */ 106f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private void ageScanResultsOut(int delay) { 107f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (delay <= 0) { 108f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle delay = mScanResultMaximumAge; //something sane 109f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 110f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle Date now = new Date(); 111f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle long milli = now.getTime(); 112f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 113f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("ageScanResultsOut delay " + Integer.valueOf(delay) + " size " 114f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.valueOf(scanResultCache.size()) + " now " + Long.valueOf(milli)); 115f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 116f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 117f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle Iterator<HashMap.Entry<String,ScanResult>> iter = scanResultCache.entrySet().iterator(); 118f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle while (iter.hasNext()) { 119f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle HashMap.Entry<String,ScanResult> entry = iter.next(); 120f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle ScanResult result = entry.getValue(); 121f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 122f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((result.seen + delay) < milli) { 123f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle iter.remove(); 124f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 125f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 126f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 127f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 128f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle void addToScanCache(List<ScanResult> scanList) { 129f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration associatedConfig; 130f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1310c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle ArrayList<NetworkKey> unknownScanResults = new ArrayList<NetworkKey>(); 1320c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle 133f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for(ScanResult result: scanList) { 134f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle result.seen = System.currentTimeMillis(); 135f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 136f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle ScanResult sr = scanResultCache.get(result.BSSID); 137f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (sr != null) { 138f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle // if there was a previous cache result for this BSSID, average the RSSI values 139f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 140f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int previous_rssi = sr.level; 141f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle long previously_seen_milli = sr.seen; 142f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 143f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle /* average RSSI with previously seen instances of this scan result */ 144f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int avg_rssi = result.level; 145f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 146f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((previously_seen_milli > 0) 147f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle && (previously_seen_milli < mScanResultMaximumAge/2)) { 148f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 149f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle /* 150f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 151f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * previously_seen_milli = 0 => RSSI = 0.5 * previous_seen_rssi + 0.5 * new_rssi 152f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 153f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * If previously_seen_milli is 15+ seconds old: 154f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * previously_seen_milli = 15000 => RSSI = new_rssi 155f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 156f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle */ 157f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 158f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle double alpha = 0.5 - (double)previously_seen_milli 159f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle / (double)mScanResultMaximumAge; 160f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 161f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle avg_rssi = (int)((double)avg_rssi * (1-alpha) + (double)previous_rssi * alpha); 162f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1630c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle 1640c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle 1650c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle 166f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 167f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle result.level = avg_rssi; 168f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 169f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //remove the previous Scan Result 170f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle scanResultCache.remove(result.BSSID); 1710c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle } else { 1720c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle if (!mNetworkScoreCache.isScoredNetwork(result)) { 1730c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle //TODO : properly handle SSID formatting, i.e. among others check for string 1740c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle //TODO : representing hexadecimal SSIDs 1750c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle WifiKey wkey = new WifiKey("\"" + result.SSID + "\"", result.BSSID); 1760c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle NetworkKey nkey = new NetworkKey(wkey); 1770c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle //if we don't know this scan result then request a score to Herrevad 1780c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle unknownScanResults.add(nkey); 1790c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle } 180f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 181f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 182f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle scanResultCache.put(result.BSSID, new ScanResult(result)); 183f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 184f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle ScanResult srn = scanResultCache.get(result.BSSID); 185f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 186f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //add this BSSID to the scanResultCache of the relevant WifiConfiguration 187f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle associatedConfig = mWifiConfigStore.updateSavedNetworkHistory(result); 188f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1890c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle //try to associate this BSSID to an existing Saved WifiConfiguration 190f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (associatedConfig == null) { 191f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle associatedConfig = mWifiConfigStore.associateWithConfiguration(result); 192f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (associatedConfig != null) { 193f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 194f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("addToScanCache save associated config " 195f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + associatedConfig.SSID + " with " + associatedConfig.SSID); 196f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 197f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiStateMachine.sendMessage(WifiManager.SAVE_NETWORK, associatedConfig); 198f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 199f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 200f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 2010c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle 2020c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle if (unknownScanResults.size() != 0) { 2030c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle NetworkKey[] newKeys = 2040c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle unknownScanResults.toArray(new NetworkKey[unknownScanResults.size()]); 2050c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle //kick the score manager, we will get updated scores asynchronously 2060c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle scoreManager.requestScores(newKeys); 2070c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle } 208f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 209f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 210f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle void logDbg(String message) { 211ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg(message, true); 212ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 213ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle 214ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle void logDbg(String message, boolean stackTrace) { 215f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle long now = SystemClock.elapsedRealtimeNanos(); 216f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle String ts = String.format("[%,d us] ", now/1000); 217ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (stackTrace) { 218ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle Log.e(TAG, ts + message + " stack:" 219ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Thread.currentThread().getStackTrace()[2].getMethodName() + " - " 220ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Thread.currentThread().getStackTrace()[3].getMethodName() + " - " 221ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Thread.currentThread().getStackTrace()[4].getMethodName() + " - " 222ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Thread.currentThread().getStackTrace()[5].getMethodName()); 223ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } else { 224ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle Log.e(TAG, ts + message); 225ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 226f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 227f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 228f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle /* called directly from WifiStateMachine */ 229f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle void newSupplicantResults() { 230f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle List<ScanResult> scanList = mWifiStateMachine.syncGetScanResultsList(); 231f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle addToScanCache(scanList); 232f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle ageScanResultsOut(mScanResultMaximumAge); 233f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (DBG) 234f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("newSupplicantResults size=" + Integer.valueOf(scanResultCache.size()) ); 235f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 236f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle attemptAutoJoin(); 237f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiConfigStore.writeKnownNetworkHistory(); 238f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 239f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 240f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 241f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 242f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle /* not used at the moment 243f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * should be a call back from WifiScanner HAL ?? 244f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * this function is not hooked and working yet, it will receive scan results from WifiScanners 245f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * with the list of IEs,then populate the capabilities by parsing the IEs and inject the scan 246f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * results as normal. 247f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle */ 248f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle void newHalScanResults() { 249f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle List<ScanResult> scanList = null;//mWifiScanner.syncGetScanResultsList(); 250f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle String akm = WifiParser.parse_akm(null, null); 251f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg(akm); 252f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle addToScanCache(scanList); 253f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle ageScanResultsOut(0); 254f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle attemptAutoJoin(); 255f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiConfigStore.writeKnownNetworkHistory(); 256f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 257f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 258f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle /* network link quality changed, called directly from WifiTrafficPoller, 259f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle or by listening to Link Quality intent */ 260f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle void linkQualitySignificantChange() { 261f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle attemptAutoJoin(); 262f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 263f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 264f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle /* 265f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * compare a WifiConfiguration against the current network, return a delta score 266f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * If not associated, and the candidate will always be better 267f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * For instance if the candidate is a home network versus an unknown public wifi, 268f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * the delta will be infinite, else compare Kepler scores etc… 269f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle ***/ 270f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private int compareNetwork(WifiConfiguration candidate) { 271f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration currentNetwork = mWifiStateMachine.getCurrentWifiConfiguration(); 272f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (currentNetwork == null) 273f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return 1000; 274f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 275f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (candidate.configKey(true).equals(currentNetwork.configKey(true))) { 276f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return -1; 277f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 278f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 279f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int order = compareWifiConfigurations(currentNetwork, candidate); 280f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 281f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (order > 0) { 282f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //ascending: currentNetwork < candidate 283f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return 10; //will try switch over to the candidate 284f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 285f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 286f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return 0; 287f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 288f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 289ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle /** 290ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * update the network history fields fo that configuration 291ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * - if userTriggered, we mark the configuration as "non selfAdded" since the user has seen it 292ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * and took over management 293ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * - if it is a "connect", remember which network were there at the point of the connect, so 294ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * as those networks get a relative lower score than the selected configuration 29562f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle * 296ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * @param netId 297ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * @param userTriggered : if the update come from WiFiManager 298ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * @param connect : if the update includes a connect 299117be607246604e875de62aa8cdd99700b77a2b4vandwalle **/ 30062f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle public void updateConfigurationHistory(int netId, boolean userTriggered, boolean connect) { 301f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration selected = mWifiConfigStore.getWifiConfiguration(netId); 302f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (selected == null) { 303f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return; 304f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 305f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 306e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle if (selected.SSID == null) { 307e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle return; 308e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle } 309e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle 31062f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (userTriggered) { 311ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle // reenable autojoin for this network, 31262f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle // since the user want to connect to this configuration 31362f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle selected.autoJoinStatus = WifiConfiguration.AUTO_JOIN_ENABLED; 31462f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle selected.selfAdded = false; 31562f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 316f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 317f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (DBG) { 318f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (selected.connectChoices != null) { 319ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory will update " 320f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.toString(netId) + " now: " 321f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.toString(selected.connectChoices.size())); 322f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else { 323ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory will update " 324f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.toString(netId)); 325f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 326f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 327f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 328ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (connect && userTriggered) { 329ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle boolean found = false; 33062f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle List<WifiConfiguration> networks = 33162f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle mWifiConfigStore.getRecentConfiguredNetworks(12000, false); 33262f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (networks != null) { 33362f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle for (WifiConfiguration config : networks) { 33462f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (DBG) 335ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory got " + config.SSID); 336f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 33762f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (selected.configKey(true).equals(config.configKey(true))) { 338ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle found = true; 33962f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle continue; 34062f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 341f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 34262f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle int rssi = WifiConfiguration.INVALID_RSSI; 34362f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (config.visibility != null) { 34462f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle rssi = config.visibility.rssi5; 34562f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (config.visibility.rssi24 > rssi) 34662f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle rssi = config.visibility.rssi24; 34762f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 34862f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (rssi < -80) { 34962f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle continue; 35062f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 351f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 352ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle //the selected configuration was preferred over a recently seen config 353ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle //hence remember the user's choice: 354ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle //add the recently seen config to the selected's connectChoices array 355ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle 356ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (selected.connectChoices == null) { 357ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle selected.connectChoices = new HashMap<String, Integer>(); 358ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 359ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle 360ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory add a choice " + selected.configKey(true) 36162f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle + " over " + config.configKey(true) + " RSSI " + Integer.toString(rssi)); 36262f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle selected.connectChoices.put(config.configKey(true), rssi); 363f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 36462f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (config.connectChoices != null) { 365ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (VDBG) { 366ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory will remove " 36762f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle + selected.configKey(true) + " from " + config.configKey(true)); 368ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 36962f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle //remove the selected from the recently seen config's array 37062f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle config.connectChoices.remove(selected.configKey(true)); 37162f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 372ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 373ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (found == false) { 374ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle // log an error for now but do something stringer later 375ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle // we will need a new scan before attempting to connect to this 376ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle // configuration anyhow and thus we can process the scan results then 377ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory try to connect to an old network!! : " 378ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + selected.configKey()); 37962f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 380f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 38162f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (selected.connectChoices != null) { 38262f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (VDBG) 383ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory " + Integer.toString(netId) 38462f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle + " now: " + Integer.toString(selected.connectChoices.size())); 38562f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 386ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle 387ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle mWifiConfigStore.writeKnownNetworkHistory(); 388f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 389f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 390f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 391f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 392f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle void printChoices(WifiConfiguration config) { 393f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int num = 0; 394f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (config.connectChoices!= null) { 395f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle num = config.connectChoices.size(); 396f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 397f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 398f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("printChoices " + config.SSID + " num choices: " + Integer.toString(num)); 399f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (config.connectChoices!= null) { 400f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for (String key : config.connectChoices.keySet()) { 401f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg(" " + key); 402f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 403f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 404f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 405f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 406f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 407ede1310be531a84faa08f02c3fd243448dd936ddvandwalle 408ede1310be531a84faa08f02c3fd243448dd936ddvandwalle 409f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle boolean hasConnectChoice(WifiConfiguration source, WifiConfiguration target) { 410f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle boolean found = false; 411f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (source == null) 412f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return false; 413f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (target == null) 414f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return false; 415f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 416f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (source.connectChoices != null) { 417f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ( source.connectChoices.get(target.configKey(true)) != null) { 418f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle found = true; 419f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 420f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 421f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 422f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (source.linkedConfigurations != null) { 423f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for (String key : source.linkedConfigurations.keySet()) { 424f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration config = mWifiConfigStore.getWifiConfiguration(key); 425f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (config != null) { 426f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (config.connectChoices != null) { 427f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (config.connectChoices.get(target.configKey(true)) != null) { 428f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle found = true; 429f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 430f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 431f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 432f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 433f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 434f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return found; 435f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 436f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 437f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int compareWifiConfigurationsRSSI(WifiConfiguration a, WifiConfiguration b) { 438f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int order = 0; 439f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int boost5 = 25; 440f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 441f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration.Visibility astatus = a.visibility; 442f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration.Visibility bstatus = b.visibility; 443f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (astatus == null || bstatus == null) { 444453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle //error -> cant happen, need to throw en exception 445f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("compareWifiConfigurations NULL band status!"); 446f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return 0; 447f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 448453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle if ((astatus.rssi5 > -70) && (bstatus.rssi5 == WifiConfiguration.INVALID_RSSI) 449f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle && ((astatus.rssi5+boost5) > (bstatus.rssi24))) { 450f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //a is seen on 5GHz with good RSSI, greater rssi than b 451f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //a is of higher priority - descending 452f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle order = -1; 453453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle } else if ((bstatus.rssi5 > -70) && (astatus.rssi5 == WifiConfiguration.INVALID_RSSI) 454f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle && ((bstatus.rssi5+boost5) > (bstatus.rssi24))) { 455f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //b is seen on 5GHz with good RSSI, greater rssi than a 456f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //a is of lower priority - ascending 457f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle order = 1; 458f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 459f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return order; 460f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 461f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 462f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int compareWifiConfigurations(WifiConfiguration a, WifiConfiguration b) { 463f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int order = 0; 464117be607246604e875de62aa8cdd99700b77a2b4vandwalle String lastSelectedConfiguration = mWifiConfigStore.getLastSelectedConfiguration(); 465f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle boolean linked = false; 466f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 467453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle if ((a.linkedConfigurations != null) && (b.linkedConfigurations != null) 468453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle && (a.autoJoinStatus == WifiConfiguration.AUTO_JOIN_ENABLED) 469453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle && (b.autoJoinStatus == WifiConfiguration.AUTO_JOIN_ENABLED)) { 470f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((a.linkedConfigurations.get(b.configKey(true))!= null) 471f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle && (b.linkedConfigurations.get(a.configKey(true))!= null)) { 472f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle linked = true; 473f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 474f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 475f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 476f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (a.ephemeral && b.ephemeral == false) { 477f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 478453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("compareWifiConfigurations ephemeral and prefers " + b.configKey() 479453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + " over " + a.configKey()); 480f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 481f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return 1; //b is of higher priority - ascending 482f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 483f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (b.ephemeral && a.ephemeral == false) { 484f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 485453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("compareWifiConfigurations ephemeral and prefers " +a.configKey() 486453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + " over " + b.configKey()); 487f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 488f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return -1; //a is of higher priority - descending 489f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 490f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 491f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int boost5 = 25; 492453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle //apply Hysteresis: boost the RSSI value of the currently connected configuration 493453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle int aRssiBoost = 0; 494453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle int bRssiBoost = 0; 495453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle if (null != mCurrentConfigurationKey) { 496453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle if (a.configKey().equals(mCurrentConfigurationKey)) { 497453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle aRssiBoost += 10; 498453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle } else if (b.configKey().equals(mCurrentConfigurationKey)) { 499453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle bRssiBoost += 10; 500453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle } 501453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle } 502f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (linked) { 503f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle // then we try prefer 5GHz, and try to ignore user's choice 504f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration.Visibility astatus = a.visibility; 505f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration.Visibility bstatus = b.visibility; 506f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (astatus == null || bstatus == null) { 507f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //error 508f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("compareWifiConfigurations NULL band status!"); 509f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return 0; 510f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 511f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 512f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 513f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("compareWifiConfigurations linked: " + Integer.toString(astatus.rssi5) 514f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + "," + Integer.toString(astatus.rssi24) + " " 515f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.toString(bstatus.rssi5) + "," 516f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.toString(bstatus.rssi24)); 517f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 518f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 519453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle if ((astatus.rssi5 > -70) && (bstatus.rssi5 <= WifiConfiguration.INVALID_RSSI) 520453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle && (astatus.rssi5+boost5+aRssiBoost) > (bstatus.rssi24+bRssiBoost)) { 521453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle //in this case: a has 5GHz and b doesn't have 5GHz 522453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle //compare a's 5GHz RSSI to b's 5GHz RSSI 523453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle 524f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //a is seen on 5GHz with good RSSI, greater rssi than b 525f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //a is of higher priority - descending 526f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle order = -10; 527f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 528f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 529453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("compareWifiConfigurations linked and prefers " + a.configKey() 530453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + " over " + b.configKey() 531f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + " due to 5GHz RSSI " + Integer.toString(astatus.rssi5) 532f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + " over: 5=" + Integer.toString(bstatus.rssi5) 533f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + ", 2.4=" + Integer.toString(bstatus.rssi5)); 534f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 535453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle } else if ((bstatus.rssi5 > -70) && (astatus.rssi5 <= WifiConfiguration.INVALID_RSSI) 536453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle && ((bstatus.rssi5+boost5+bRssiBoost) > (astatus.rssi24+aRssiBoost))) { 537453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle //in this case: b has 5GHz and a doesn't have 5GHz 538453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle 539f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //b is seen on 5GHz with good RSSI, greater rssi than a 540f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //a is of lower priority - ascending 541f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 542453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("compareWifiConfigurations linked and prefers " + b.configKey() 543453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + " over " + a.configKey() + " due to 5GHz RSSI " 544f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.toString(astatus.rssi5) + " over: 5=" 545f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.toString(bstatus.rssi5) + ", 2.4=" 546f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.toString(bstatus.rssi5)); 547f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 548f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle order = 10; 549453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle } else { 550453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle //TODO: handle cases where configurations are dual band 551f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 552f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 553ede1310be531a84faa08f02c3fd243448dd936ddvandwalle 554ede1310be531a84faa08f02c3fd243448dd936ddvandwalle //compare by user's choice. 555f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (hasConnectChoice(a, b)) { 556f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //a is of higher priority - descending 557f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle order = order -2; 558f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 559453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("compareWifiConfigurations prefers -2 " + a.configKey() 560453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + " over " + b.configKey() 561ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + " due to user choice order -> " + Integer.toString(order)); 562f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 563f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 564f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 565f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (hasConnectChoice(b, a)) { 566f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //a is of lower priority - ascending 567f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle order = order + 2; 568f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 569453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("compareWifiConfigurations prefers +2 " + b.configKey() + " over " 570453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + a.configKey() + " due to user choice order ->" + Integer.toString(order)); 571f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 572f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 573f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 574ede1310be531a84faa08f02c3fd243448dd936ddvandwalle //TODO count the number of association rejection 575ede1310be531a84faa08f02c3fd243448dd936ddvandwalle // and use this to adjust the order by more than +/- 3 576ede1310be531a84faa08f02c3fd243448dd936ddvandwalle if ((a.status == WifiConfiguration.Status.DISABLED) 577ede1310be531a84faa08f02c3fd243448dd936ddvandwalle && (a.disableReason == WifiConfiguration.DISABLED_ASSOCIATION_REJECT)) { 578ede1310be531a84faa08f02c3fd243448dd936ddvandwalle //a is of lower priority - ascending 579ede1310be531a84faa08f02c3fd243448dd936ddvandwalle //lower the comparison score a bit 580ede1310be531a84faa08f02c3fd243448dd936ddvandwalle order = order +3; 581ede1310be531a84faa08f02c3fd243448dd936ddvandwalle } 582ede1310be531a84faa08f02c3fd243448dd936ddvandwalle if ((b.status == WifiConfiguration.Status.DISABLED) 583ede1310be531a84faa08f02c3fd243448dd936ddvandwalle && (b.disableReason == WifiConfiguration.DISABLED_ASSOCIATION_REJECT)) { 584ede1310be531a84faa08f02c3fd243448dd936ddvandwalle //a is of higher priority - descending 585ede1310be531a84faa08f02c3fd243448dd936ddvandwalle //lower the comparison score a bit 586ede1310be531a84faa08f02c3fd243448dd936ddvandwalle order = order -3; 587ede1310be531a84faa08f02c3fd243448dd936ddvandwalle } 588ede1310be531a84faa08f02c3fd243448dd936ddvandwalle 589ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if ((lastSelectedConfiguration != null) 590ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle && a.configKey().equals(lastSelectedConfiguration)) { 591ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle // a is the last selected configuration, so keep it above connect choices 592ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle //by giving a -4 (whereas connect choice preference gives +2) 593ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle order = order - 4; 594ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (VDBG) { 595453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("compareWifiConfigurations prefers -4 " + a.configKey() 596453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + " over " + b.configKey() + " because a is the last selected -> " 597ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Integer.toString(order)); 598ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 599ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } else if ((lastSelectedConfiguration != null) 600ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle && b.configKey().equals(lastSelectedConfiguration)) { 601ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle // b is the last selected configuration, so keep it above connect choices 602ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle //by giving a +4 (whereas connect choice preference gives -2) 603ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle order = order + 4; 604ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (VDBG) { 605453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("compareWifiConfigurations prefers +4 " + a.configKey() 606453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + " over " + b.configKey() + " because b is the last selected -> " 607ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Integer.toString(order)); 608ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 609ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 610ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle 611f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (order == 0) { 612f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //we don't know anything - pick the last seen i.e. K behavior 613f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //we should do this only for recently picked configurations 614f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (a.priority > b.priority) { 615f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //a is of higher priority - descending 616f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 617453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("compareWifiConfigurations prefers -1 " + a.configKey() + " over " 618453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + b.configKey() + " due to priority"); 619f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 620f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 621f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle order = -1; 622f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else if (a.priority < b.priority) { 623f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //a is of lower priority - ascending 624f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 625453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("compareWifiConfigurations prefers +1 " + b.configKey() + " over " 626453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + a.configKey() + " due to priority"); 627f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 628f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 629f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle order = 1; 630f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else { 631f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //maybe just look at RSSI or band 632f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 633453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("compareWifiConfigurations prefers +1 " + b.configKey() + " over " 634453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + a.configKey() + " due to nothing"); 635f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 636f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 637f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle order = compareWifiConfigurationsRSSI(a, b); //compare RSSI 638f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 639f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 640f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 641f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle String sorder = " == "; 642f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (order > 0) 643f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle sorder = " < "; 644f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (order < 0) 645f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle sorder = " > "; 646f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 647f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 648453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("compareWifiConfigurations Done: " + a.configKey() + sorder 649453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + b.configKey() + " order " + Integer.toString(order)); 650f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 651f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 652f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return order; 653f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 654f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 655f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle /* attemptAutoJoin function implement the core of the a network switching algorithm */ 656f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle void attemptAutoJoin() { 657453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle //reset the currentConfiguration Key, and set it only if WifiStateMachine and 658453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle // supplicant agree 659453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle mCurrentConfigurationKey = null; 660453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle WifiConfiguration currentConfiguration = mWifiStateMachine.getCurrentWifiConfiguration(); 661453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle 662f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration candidate = null; 663f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 664f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle /* obtain the subset of recently seen networks */ 665f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle List<WifiConfiguration> list = mWifiConfigStore.getRecentConfiguredNetworks(3000, true); 666f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (list == null) { 667f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) logDbg("attemptAutoJoin nothing"); 668f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return; 669f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 670f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 671f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle /* find the currently connected network: ask the supplicant directly */ 672f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle String val = mWifiNative.status(); 673f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle String status[] = val.split("\\r?\\n"); 674f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 675f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("attemptAutoJoin() status=" + val + " split=" 676f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.toString(status.length)); 677f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 678f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 679f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int currentNetId = -1; 680f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for (String key : status) { 681f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (key.regionMatches(0, "id=", 0, 3)) { 682f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int idx = 3; 683f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle currentNetId = 0; 684f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle while (idx < key.length()) { 685f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle char c = key.charAt(idx); 686f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 687f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((c >= 0x30) && (c <= 0x39)) { 688f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle currentNetId *= 10; 689f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle currentNetId += c - 0x30; 690f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle idx++; 691f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else { 692f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle break; 693f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 694f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 695f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 696f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 697ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (DBG) { 698ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle logDbg("attemptAutoJoin() num recent config " + Integer.toString(list.size()) 699ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle + " ---> currentId=" + Integer.toString(currentNetId)); 700ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 701f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 702453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle if (currentConfiguration != null) { 703453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle if (currentNetId != currentConfiguration.networkId) { 704453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("attemptAutoJoin() ERROR wpa_supplicant out of sync nid=" 705453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + Integer.toString(currentNetId) + " WifiStateMachine=" 706453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + Integer.toString(currentConfiguration.networkId)); 707453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle //I think this can happen due do race conditions, now what to do?? 708453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle // -> throw an exception, or, 709453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle // -> dont use the current configuration at all for autojoin 710453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle //and hope that autojoining will kick us out of this state. 711453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle currentConfiguration = null; 712453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle } else { 713453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle mCurrentConfigurationKey = currentConfiguration.configKey(); 714453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle } 715453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle } 716453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle 717f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle /* select Best Network candidate from known WifiConfigurations */ 718f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for (WifiConfiguration config : list) { 719f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((config.status == WifiConfiguration.Status.DISABLED) 720f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle && (config.disableReason == WifiConfiguration.DISABLED_AUTH_FAILURE)) { 721ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (DBG) { 722ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle logDbg("attemptAutoJoin skip candidate due to auth failure key " 723ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle + config.configKey(true)); 724ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 725f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle continue; 726f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 727453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle 728e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle if (config.SSID == null) { 729e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle return; 730e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle } 731e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle 732453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle if (config.autoJoinStatus >= WifiConfiguration.AUTO_JOIN_TEMPORARY_DISABLED) { 733453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle //avoid temporarily disabled networks altogether 734453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle //TODO: implement a better logic which will reenable the network after some time 735ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (DBG) { 736ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle logDbg("attemptAutoJoin skip candidate due to auto join status " 737ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle + Integer.toString(config.autoJoinStatus) + " key " 738ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle + config.configKey(true)); 739ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 740f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle continue; 741f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 742f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 743f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (config.networkId == currentNetId) { 744ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (DBG) { 745ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle logDbg("attemptAutoJoin skip current candidate " + Integer.toString(currentNetId) 746ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle + " key " + config.configKey(true)); 747ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 748f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle continue; 749f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 750f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 751ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (DBG) { 752ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle logDbg("attemptAutoJoin trying candidate id=" + config.networkId + " " 753ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle + config.SSID + " key " + config.configKey(true)); 754ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 755f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 756f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (candidate == null) { 757f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle candidate = config; 758f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else { 759f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 760453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("attemptAutoJoin will compare candidate " + candidate.configKey() 761453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + " with " + config.configKey() + " key " + config.configKey(true)); 762f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 763f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 764f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int order = compareWifiConfigurations(candidate, config); 765f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 766f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 767f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("attemptAutoJoin did compare candidate " + Integer.toString(order)); 768f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 769f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 770f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (order > 0) { 771f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //ascending : candidate < config 772f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle candidate = config; 773f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 774f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 775f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 776f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 777f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle /* now, go thru scan result to try finding a better Herrevad network */ 778f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (mNetworkScoreCache != null) { 779f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int rssi5 = WifiConfiguration.INVALID_RSSI; 780f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int rssi24 = WifiConfiguration.INVALID_RSSI; 781f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration.Visibility visibility; 782f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (candidate != null) { 783f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle rssi5 = candidate.visibility.rssi5; 784f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle rssi24 = candidate.visibility.rssi24; 785f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 786f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 787f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //get current date 788f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle Date now = new Date(); 789f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle long now_ms = now.getTime(); 790f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 791f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (rssi5 < -60 && rssi24 < -70) { 792f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for (ScanResult result : scanResultCache.values()) { 793f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((now_ms - result.seen) < 3000) { 794f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int score = mNetworkScoreCache.getNetworkScore(result); 795f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (score > 0) { 796f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle // try any arbitrary formula for now, adding apple and oranges, 797f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle // i.e. adding network score and "dBm over noise" 798f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (result.frequency < 4000) { 799f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((result.level + score) > (rssi24 -40)) { 800f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle // force it as open, TBD should we otherwise verify that this 801f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle // BSSID only supports open?? 802f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle result.capabilities = ""; 803f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 804f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //switch to this scan result 805f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle candidate = 806f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiConfigStore.wifiConfigurationFromScanResult(result); 807f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle candidate.ephemeral = true; 808f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 809f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else { 810f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((result.level + score) > (rssi5 -30)) { 811f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle // force it as open, TBD should we otherwise verify that this 812f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle // BSSID only supports open?? 813f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle result.capabilities = ""; 814f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 815f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //switch to this scan result 816f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle candidate = 817f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiConfigStore.wifiConfigurationFromScanResult(result); 818f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle candidate.ephemeral = true; 819f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 820f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 821f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 822f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 823f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 824f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 825f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 826f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (candidate != null) { 827453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle /* if candidate is found, check the state of the connection so as 828453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle to decide if we should be acting on this candidate and switching over */ 829453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle if (VDBG) { 830453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("attemptAutoJoin did find candidate " + candidate.configKey() 831f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + " key " + candidate.configKey(true)); 832453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle } 833f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 834f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int networkDelta = compareNetwork(candidate); 835ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (DBG && (networkDelta > 0)) { 836453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("attemptAutoJoin did find candidate " + candidate.configKey() 837f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + " for delta " + Integer.toString(networkDelta)); 838ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 839f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle /* ASK traffic poller permission to switch: 840f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for instance, 841f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if user is currently streaming voice traffic, 842f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle then don’t switch regardless of the delta */ 843f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 844f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (mWifiTrafficPoller.shouldSwitchNetwork(networkDelta)) { 845f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (mStaStaSupported) { 846453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("mStaStaSupported --> error do nothing now "); 847f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else { 848f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (DBG) { 849453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("AutoJoin auto connect with netId " 850f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.toString(candidate.networkId) 851453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + " to " + candidate.configKey()); 852f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 853f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 854f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiStateMachine.sendMessage(WifiStateMachine.CMD_AUTO_CONNECT, 855f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle candidate.networkId); 856f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //mWifiConfigStore.enableNetworkWithoutBroadcast(candidate.networkId, true); 857f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 858f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //we would do the below only if we want to persist the new choice 859f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //mWifiConfigStore.selectNetwork(candidate.networkId); 860f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 861f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 862f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 863f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 864f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) logDbg("Done attemptAutoJoin"); 865f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 866f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle} 867f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 868