1c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein/* 2c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * Copyright (C) 2015 The Android Open Source Project 3c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * 4c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * Licensed under the Apache License, Version 2.0 (the "License"); 5c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * you may not use this file except in compliance with the License. 6c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * You may obtain a copy of the License at 7c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * 8c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * http://www.apache.org/licenses/LICENSE-2.0 9c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * 10c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * Unless required by applicable law or agreed to in writing, software 11c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * distributed under the License is distributed on an "AS IS" BASIS, 12c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * See the License for the specific language governing permissions and 14c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * limitations under the License. 15c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein */ 164d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 174d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandepackage com.android.server.wifi; 184d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 194d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandeimport android.net.wifi.ScanResult; 204d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandeimport android.net.wifi.WifiConfiguration; 21e3e4fad6e9b2022018a33507e93a39c6446f9916Pierre Vandwalleimport android.os.SystemClock; 22c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silbersteinimport android.util.Log; 234d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 244d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandeimport com.android.server.wifi.hotspot2.PasspointMatch; 254d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandeimport com.android.server.wifi.hotspot2.PasspointMatchInfo; 264d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandeimport com.android.server.wifi.hotspot2.pps.HomeSP; 274d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 284d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandeimport java.util.ArrayList; 294d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandeimport java.util.Collection; 304d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandeimport java.util.Collections; 314d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandeimport java.util.Comparator; 324d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandeimport java.util.Iterator; 337713c37038f24f06039e5c4c3c191e10a1b9e159Randy Panimport java.util.concurrent.ConcurrentHashMap; 344d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 35c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein/** 36c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * Maps BSSIDs to their individual ScanDetails for a given WifiConfiguration. 37c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein */ 38c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silbersteinpublic class ScanDetailCache { 398eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande 408eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande private static final String TAG = "ScanDetailCache"; 41c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein private static final boolean DBG = false; 428eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande 434d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande private WifiConfiguration mConfig; 447713c37038f24f06039e5c4c3c191e10a1b9e159Randy Pan private ConcurrentHashMap<String, ScanDetail> mMap; 457713c37038f24f06039e5c4c3c191e10a1b9e159Randy Pan private ConcurrentHashMap<String, PasspointMatchInfo> mPasspointMatches; 46c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein 474d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande ScanDetailCache(WifiConfiguration config) { 484d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande mConfig = config; 497713c37038f24f06039e5c4c3c191e10a1b9e159Randy Pan mMap = new ConcurrentHashMap(16, 0.75f, 2); 507713c37038f24f06039e5c4c3c191e10a1b9e159Randy Pan mPasspointMatches = new ConcurrentHashMap(16, 0.75f, 2); 514d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 524d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 534d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande void put(ScanDetail scanDetail) { 544d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande put(scanDetail, null, null); 554d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 564d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 574d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande void put(ScanDetail scanDetail, PasspointMatch match, HomeSP homeSp) { 58a547460e835d6dfde84eda72df470846d11ba807Vinit Deshpande 594d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande mMap.put(scanDetail.getBSSIDString(), scanDetail); 60a547460e835d6dfde84eda72df470846d11ba807Vinit Deshpande 61a547460e835d6dfde84eda72df470846d11ba807Vinit Deshpande if (match != null && homeSp != null) { 62a547460e835d6dfde84eda72df470846d11ba807Vinit Deshpande mPasspointMatches.put(scanDetail.getBSSIDString(), 63a547460e835d6dfde84eda72df470846d11ba807Vinit Deshpande new PasspointMatchInfo(match, scanDetail, homeSp)); 64a547460e835d6dfde84eda72df470846d11ba807Vinit Deshpande } 654d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 664d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 674d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande ScanResult get(String bssid) { 684d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande ScanDetail scanDetail = getScanDetail(bssid); 694d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande return scanDetail == null ? null : scanDetail.getScanResult(); 704d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 714d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 724d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande ScanDetail getScanDetail(String bssid) { 734d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande return mMap.get(bssid); 744d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 754d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 764d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande void remove(String bssid) { 774d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande mMap.remove(bssid); 784d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 794d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 804d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande int size() { 814d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande return mMap.size(); 824d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 834d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 844d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande boolean isEmpty() { 854d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande return size() == 0; 864d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 874d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 884d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande ScanDetail getFirst() { 894d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande Iterator<ScanDetail> it = mMap.values().iterator(); 904d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande return it.hasNext() ? it.next() : null; 914d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 924d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 934d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande Collection<String> keySet() { 944d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande return mMap.keySet(); 954d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 964d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 974d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande Collection<ScanDetail> values() { 984d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande return mMap.values(); 994d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 1004d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 101c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein /** 102c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * Method to reduce the cache to the given size by removing the oldest entries. 103c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * 104c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * @param num int target cache size 105c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein */ 1064d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande public void trim(int num) { 1074d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande int currentSize = mMap.size(); 1084d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande if (currentSize <= num) { 1094d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande return; // Nothing to trim 1104d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 1114d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande ArrayList<ScanDetail> list = new ArrayList<ScanDetail>(mMap.values()); 1124d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande if (list.size() != 0) { 1134d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande // Sort by descending timestamp 1144d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande Collections.sort(list, new Comparator() { 1154d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande public int compare(Object o1, Object o2) { 1164d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande ScanDetail a = (ScanDetail) o1; 1174d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande ScanDetail b = (ScanDetail) o2; 1184d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande if (a.getSeen() > b.getSeen()) { 1194d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande return 1; 1204d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 1214d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande if (a.getSeen() < b.getSeen()) { 1224d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande return -1; 1234d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 1244d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande return a.getBSSIDString().compareTo(b.getBSSIDString()); 1254d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 1264d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande }); 1274d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 128c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein for (int i = 0; i < currentSize - num; i++) { 1294d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande // Remove oldest results from scan cache 1304d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande ScanDetail result = list.get(i); 1314d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande mMap.remove(result.getBSSIDString()); 1324d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande mPasspointMatches.remove(result.getBSSIDString()); 1334d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 1344d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 1354d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 1364d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande /* @hide */ 1374d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande private ArrayList<ScanDetail> sort() { 1384d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande ArrayList<ScanDetail> list = new ArrayList<ScanDetail>(mMap.values()); 1394d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande if (list.size() != 0) { 1404d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande Collections.sort(list, new Comparator() { 1414d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande public int compare(Object o1, Object o2) { 142c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein ScanResult a = ((ScanDetail) o1).getScanResult(); 143c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein ScanResult b = ((ScanDetail) o2).getScanResult(); 1444d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande if (a.numIpConfigFailures > b.numIpConfigFailures) { 1454d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande return 1; 1464d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 1474d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande if (a.numIpConfigFailures < b.numIpConfigFailures) { 1484d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande return -1; 1494d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 1504d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande if (a.seen > b.seen) { 1514d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande return -1; 1524d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 1534d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande if (a.seen < b.seen) { 1544d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande return 1; 1554d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 1564d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande if (a.level > b.level) { 1574d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande return -1; 1584d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 1594d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande if (a.level < b.level) { 1604d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande return 1; 1614d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 1624d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande return a.BSSID.compareTo(b.BSSID); 1634d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 1644d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande }); 1654d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 1664d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande return list; 1674d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 1684d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 169c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein /** 170c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * Method to get cached scan results that are less than 'age' old. 171c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * 172c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * @param age long Time window of desired results. 173c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * @return WifiConfiguration.Visibility matches in the given visibility 174c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein */ 1754d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande public WifiConfiguration.Visibility getVisibilityByRssi(long age) { 1764d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande WifiConfiguration.Visibility status = new WifiConfiguration.Visibility(); 1774d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 1784d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande long now_ms = System.currentTimeMillis(); 179cb59612d2af82044ee74e8f595c9a40498db14b4Pierre Vandwalle long now_elapsed_ms = SystemClock.elapsedRealtime(); 180c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein for (ScanDetail scanDetail : values()) { 1814d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande ScanResult result = scanDetail.getScanResult(); 182c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein if (scanDetail.getSeen() == 0) { 1834d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande continue; 184c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein } 1854d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 1864d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande if (result.is5GHz()) { 1874d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande //strictly speaking: [4915, 5825] 1884d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande //number of known BSSID on 5GHz band 1894d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande status.num5 = status.num5 + 1; 1904d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } else if (result.is24GHz()) { 1914d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande //strictly speaking: [2412, 2482] 1924d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande //number of known BSSID on 2.4Ghz band 1934d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande status.num24 = status.num24 + 1; 1944d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 1954d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 196e3e4fad6e9b2022018a33507e93a39c6446f9916Pierre Vandwalle if (result.timestamp != 0) { 197e3e4fad6e9b2022018a33507e93a39c6446f9916Pierre Vandwalle if (DBG) { 198e3e4fad6e9b2022018a33507e93a39c6446f9916Pierre Vandwalle Log.e("getVisibilityByRssi", " considering " + result.SSID + " " + result.BSSID 199c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein + " elapsed=" + now_elapsed_ms + " timestamp=" + result.timestamp 200c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein + " age = " + age); 201e3e4fad6e9b2022018a33507e93a39c6446f9916Pierre Vandwalle } 202c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein if ((now_elapsed_ms - (result.timestamp / 1000)) > age) continue; 203e3e4fad6e9b2022018a33507e93a39c6446f9916Pierre Vandwalle } else { 204c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein // This checks the time at which we have received the scan result from supplicant 205e3e4fad6e9b2022018a33507e93a39c6446f9916Pierre Vandwalle if ((now_ms - result.seen) > age) continue; 206e3e4fad6e9b2022018a33507e93a39c6446f9916Pierre Vandwalle } 2074d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 2084d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande if (result.is5GHz()) { 2094d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande if (result.level > status.rssi5) { 2104d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande status.rssi5 = result.level; 2114d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande status.age5 = result.seen; 2124d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande status.BSSID5 = result.BSSID; 2134d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 2144d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } else if (result.is24GHz()) { 2154d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande if (result.level > status.rssi24) { 2164d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande status.rssi24 = result.level; 2174d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande status.age24 = result.seen; 2184d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande status.BSSID24 = result.BSSID; 2194d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 2204d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 2214d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 2224d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 2234d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande return status; 2244d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 2254d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 226c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein /** 227c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * Method returning the Visibility based on passpoint match time. 228c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * 229c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * @param age long Desired time window for matches. 230c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * @return WifiConfiguration.Visibility matches in the given visibility 231c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein */ 2324d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande public WifiConfiguration.Visibility getVisibilityByPasspointMatch(long age) { 2334d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 2344d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande long now_ms = System.currentTimeMillis(); 2358eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande PasspointMatchInfo pmiBest24 = null, pmiBest5 = null; 2368eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande 237c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein for (PasspointMatchInfo pmi : mPasspointMatches.values()) { 2388eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande ScanDetail scanDetail = pmi.getScanDetail(); 2398eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande if (scanDetail == null) continue; 2404d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande ScanResult result = scanDetail.getScanResult(); 2418eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande if (result == null) continue; 2428eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande 243c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein if (scanDetail.getSeen() == 0) continue; 2444d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 2454d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande if ((now_ms - result.seen) > age) continue; 2464d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 2474d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande if (result.is5GHz()) { 2488eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande if (pmiBest5 == null || pmiBest5.compareTo(pmi) < 0) { 2498eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande pmiBest5 = pmi; 2504d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 2514d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } else if (result.is24GHz()) { 2528eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande if (pmiBest24 == null || pmiBest24.compareTo(pmi) < 0) { 2538eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande pmiBest24 = pmi; 2544d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 2554d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 2564d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 2574d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 2588eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande WifiConfiguration.Visibility status = new WifiConfiguration.Visibility(); 2598eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande String logMsg = "Visiblity by passpoint match returned "; 2608eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande if (pmiBest5 != null) { 2618eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande ScanResult result = pmiBest5.getScanDetail().getScanResult(); 2628eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande status.rssi5 = result.level; 2638eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande status.age5 = result.seen; 2648eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande status.BSSID5 = result.BSSID; 2658eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande logMsg += "5 GHz BSSID of " + result.BSSID; 2668eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande } 2678eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande if (pmiBest24 != null) { 2688eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande ScanResult result = pmiBest24.getScanDetail().getScanResult(); 2698eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande status.rssi24 = result.level; 2708eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande status.age24 = result.seen; 2718eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande status.BSSID24 = result.BSSID; 2728eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande logMsg += "2.4 GHz BSSID of " + result.BSSID; 2738eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande } 2748eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande 2758eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande Log.d(TAG, logMsg); 2768eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande 2774d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande return status; 2784d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 2794d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 280c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein /** 281c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * Method to get scan matches for the desired time window. Returns matches by passpoint time if 282c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * the WifiConfiguration is passpoint. 283c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * 284c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * @param age long desired time for matches. 285c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * @return WifiConfiguration.Visibility matches in the given visibility 286c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein */ 2874d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande public WifiConfiguration.Visibility getVisibility(long age) { 2884d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande if (mConfig.isPasspoint()) { 2894d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande return getVisibilityByPasspointMatch(age); 2904d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } else { 2914d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande return getVisibilityByRssi(age); 2924d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 2934d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 2944d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 2954d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 2964d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 2974d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande @Override 2984d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande public String toString() { 2994d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande StringBuilder sbuf = new StringBuilder(); 3004d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande sbuf.append("Scan Cache: ").append('\n'); 3014d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 3024d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande ArrayList<ScanDetail> list = sort(); 3034d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande long now_ms = System.currentTimeMillis(); 3044d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande if (list.size() > 0) { 3054d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande for (ScanDetail scanDetail : list) { 3064d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande ScanResult result = scanDetail.getScanResult(); 3074d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande long milli = now_ms - scanDetail.getSeen(); 3084d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande long ageSec = 0; 3094d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande long ageMin = 0; 3104d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande long ageHour = 0; 3114d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande long ageMilli = 0; 3124d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande long ageDay = 0; 3134d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande if (now_ms > scanDetail.getSeen() && scanDetail.getSeen() > 0) { 3144d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande ageMilli = milli % 1000; 3154d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande ageSec = (milli / 1000) % 60; 316c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein ageMin = (milli / (60 * 1000)) % 60; 317c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein ageHour = (milli / (60 * 60 * 1000)) % 24; 318c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein ageDay = (milli / (24 * 60 * 60 * 1000)); 3194d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 3204d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande sbuf.append("{").append(result.BSSID).append(",").append(result.frequency); 3214d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande sbuf.append(",").append(String.format("%3d", result.level)); 3224d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande if (ageSec > 0 || ageMilli > 0) { 3234d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande sbuf.append(String.format(",%4d.%02d.%02d.%02d.%03dms", ageDay, 3244d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande ageHour, ageMin, ageSec, ageMilli)); 3254d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 3264d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande if (result.numIpConfigFailures > 0) { 3274d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande sbuf.append(",ipfail="); 3284d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande sbuf.append(result.numIpConfigFailures); 3294d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 3304d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande sbuf.append("} "); 3314d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 3324d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande sbuf.append('\n'); 3334d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 3344d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 3354d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande return sbuf.toString(); 3364d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 3374d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 3384d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande} 339