[go: nahoru, domu]

ScanDetailCache.java revision 4d381bc39f5263effdae73ec99065eb299b806ca
14d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
24d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandepackage com.android.server.wifi;
34d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
44d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandeimport android.net.wifi.ScanResult;
54d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandeimport android.net.wifi.WifiConfiguration;
64d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
74d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandeimport com.android.server.wifi.ScanDetail;
84d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandeimport com.android.server.wifi.hotspot2.PasspointMatch;
94d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandeimport com.android.server.wifi.hotspot2.PasspointMatchInfo;
104d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandeimport com.android.server.wifi.hotspot2.pps.HomeSP;
114d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
124d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandeimport java.util.ArrayList;
134d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandeimport java.util.Collection;
144d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandeimport java.util.Collections;
154d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandeimport java.util.Comparator;
164d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandeimport java.util.HashMap;
174d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandeimport java.util.Iterator;
184d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandeimport java.util.List;
194d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
204d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandeclass ScanDetailCache {
214d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    private WifiConfiguration mConfig;
224d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    private HashMap<String, ScanDetail> mMap;
234d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    private HashMap<String, PasspointMatchInfo> mPasspointMatches;
244d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
254d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    ScanDetailCache(WifiConfiguration config) {
264d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        mConfig = config;
274d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        mMap = new HashMap();
284d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        mPasspointMatches = new HashMap();
294d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    }
304d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
314d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    void put(ScanDetail scanDetail) {
324d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        put(scanDetail, null, null);
334d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    }
344d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
354d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    void put(ScanDetail scanDetail, PasspointMatch match, HomeSP homeSp) {
364d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        mMap.put(scanDetail.getBSSIDString(), scanDetail);
374d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        mPasspointMatches.put(scanDetail.getBSSIDString(),
384d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                new PasspointMatchInfo(match, scanDetail, homeSp));
394d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    }
404d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
414d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    ScanResult get(String bssid) {
424d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        ScanDetail scanDetail = getScanDetail(bssid);
434d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        return scanDetail == null ? null : scanDetail.getScanResult();
444d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    }
454d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
464d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    ScanDetail getScanDetail(String bssid) {
474d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        return mMap.get(bssid);
484d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    }
494d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
504d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    void remove(String bssid) {
514d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        mMap.remove(bssid);
524d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    }
534d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
544d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    int size() {
554d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        return mMap.size();
564d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    }
574d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
584d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    boolean isEmpty() {
594d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        return size() == 0;
604d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    }
614d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
624d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    ScanDetail getFirst() {
634d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        Iterator<ScanDetail> it = mMap.values().iterator();
644d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        return it.hasNext() ? it.next() : null;
654d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    }
664d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
674d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    Collection<String> keySet() {
684d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        return mMap.keySet();
694d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    }
704d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
714d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    Collection<ScanDetail> values() {
724d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        return mMap.values();
734d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    }
744d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
754d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    public void trim(int num) {
764d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        int currentSize = mMap.size();
774d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        if (currentSize <= num) {
784d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            return; // Nothing to trim
794d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        }
804d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        ArrayList<ScanDetail> list = new ArrayList<ScanDetail>(mMap.values());
814d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        if (list.size() != 0) {
824d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            // Sort by descending timestamp
834d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            Collections.sort(list, new Comparator() {
844d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                public int compare(Object o1, Object o2) {
854d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    ScanDetail a = (ScanDetail) o1;
864d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    ScanDetail b = (ScanDetail) o2;
874d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    if (a.getSeen() > b.getSeen()) {
884d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                        return 1;
894d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    }
904d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    if (a.getSeen() < b.getSeen()) {
914d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                        return -1;
924d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    }
934d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    return a.getBSSIDString().compareTo(b.getBSSIDString());
944d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                }
954d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            });
964d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        }
974d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        for (int i = 0; i < currentSize - num ; i++) {
984d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            // Remove oldest results from scan cache
994d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            ScanDetail result = list.get(i);
1004d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            mMap.remove(result.getBSSIDString());
1014d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            mPasspointMatches.remove(result.getBSSIDString());
1024d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        }
1034d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    }
1044d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
1054d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    /* @hide */
1064d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    private ArrayList<ScanDetail> sort() {
1074d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        ArrayList<ScanDetail> list = new ArrayList<ScanDetail>(mMap.values());
1084d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        if (list.size() != 0) {
1094d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            Collections.sort(list, new Comparator() {
1104d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                public int compare(Object o1, Object o2) {
1114d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    ScanResult a = ((ScanDetail)o1).getScanResult();
1124d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    ScanResult b = ((ScanDetail)o2).getScanResult();
1134d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    if (a.numIpConfigFailures > b.numIpConfigFailures) {
1144d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                        return 1;
1154d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    }
1164d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    if (a.numIpConfigFailures < b.numIpConfigFailures) {
1174d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                        return -1;
1184d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    }
1194d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    if (a.seen > b.seen) {
1204d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                        return -1;
1214d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    }
1224d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    if (a.seen < b.seen) {
1234d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                        return 1;
1244d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    }
1254d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    if (a.level > b.level) {
1264d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                        return -1;
1274d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    }
1284d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    if (a.level < b.level) {
1294d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                        return 1;
1304d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    }
1314d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    return a.BSSID.compareTo(b.BSSID);
1324d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                }
1334d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            });
1344d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        }
1354d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        return list;
1364d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    }
1374d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
1384d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    public WifiConfiguration.Visibility getVisibilityByRssi(long age) {
1394d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        WifiConfiguration.Visibility status = new WifiConfiguration.Visibility();
1404d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
1414d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        long now_ms = System.currentTimeMillis();
1424d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        for(ScanDetail scanDetail : values()) {
1434d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            ScanResult result = scanDetail.getScanResult();
1444d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            if (scanDetail.getSeen() == 0)
1454d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                continue;
1464d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
1474d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            if (result.is5GHz()) {
1484d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                //strictly speaking: [4915, 5825]
1494d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                //number of known BSSID on 5GHz band
1504d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                status.num5 = status.num5 + 1;
1514d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            } else if (result.is24GHz()) {
1524d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                //strictly speaking: [2412, 2482]
1534d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                //number of known BSSID on 2.4Ghz band
1544d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                status.num24 = status.num24 + 1;
1554d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            }
1564d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
1574d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            if ((now_ms - result.seen) > age) continue;
1584d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
1594d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            if (result.is5GHz()) {
1604d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                if (result.level > status.rssi5) {
1614d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    status.rssi5 = result.level;
1624d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    status.age5 = result.seen;
1634d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    status.BSSID5 = result.BSSID;
1644d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                }
1654d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            } else if (result.is24GHz()) {
1664d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                if (result.level > status.rssi24) {
1674d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    status.rssi24 = result.level;
1684d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    status.age24 = result.seen;
1694d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    status.BSSID24 = result.BSSID;
1704d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                }
1714d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            }
1724d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        }
1734d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
1744d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        return status;
1754d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    }
1764d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
1774d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    public WifiConfiguration.Visibility getVisibilityByPasspointMatch(long age) {
1784d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        WifiConfiguration.Visibility status = new WifiConfiguration.Visibility();
1794d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
1804d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        long now_ms = System.currentTimeMillis();
1814d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        for(ScanDetail scanDetail : values()) {
1824d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            ScanResult result = scanDetail.getScanResult();
1834d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            if (scanDetail.getSeen() == 0)
1844d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                continue;
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
1964d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            if ((now_ms - result.seen) > age) continue;
1974d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
1984d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            if (result.is5GHz()) {
1994d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                if (result.level > status.rssi5) {
2004d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    status.rssi5 = result.level;
2014d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    status.age5 = result.seen;
2024d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    status.BSSID5 = result.BSSID;
2034d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                }
2044d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            } else if (result.is24GHz()) {
2054d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                if (result.level > status.rssi24) {
2064d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    status.rssi24 = result.level;
2074d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    status.age24 = result.seen;
2084d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    status.BSSID24 = result.BSSID;
2094d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                }
2104d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            }
2114d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        }
2124d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
2134d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        return status;
2144d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    }
2154d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
2164d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    public WifiConfiguration.Visibility getVisibility(long age) {
2174d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        if (mConfig.isPasspoint()) {
2184d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            return getVisibilityByPasspointMatch(age);
2194d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        } else {
2204d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            return getVisibilityByRssi(age);
2214d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        }
2224d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    }
2234d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
2244d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
2254d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
2264d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    @Override
2274d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    public String toString() {
2284d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        StringBuilder sbuf = new StringBuilder();
2294d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        sbuf.append("Scan Cache:  ").append('\n');
2304d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
2314d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        ArrayList<ScanDetail> list = sort();
2324d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        long now_ms = System.currentTimeMillis();
2334d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        if (list.size() > 0) {
2344d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            for (ScanDetail scanDetail : list) {
2354d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                ScanResult result = scanDetail.getScanResult();
2364d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                long milli = now_ms - scanDetail.getSeen();
2374d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                long ageSec = 0;
2384d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                long ageMin = 0;
2394d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                long ageHour = 0;
2404d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                long ageMilli = 0;
2414d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                long ageDay = 0;
2424d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                if (now_ms > scanDetail.getSeen() && scanDetail.getSeen() > 0) {
2434d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    ageMilli = milli % 1000;
2444d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    ageSec   = (milli / 1000) % 60;
2454d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    ageMin   = (milli / (60*1000)) % 60;
2464d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    ageHour  = (milli / (60*60*1000)) % 24;
2474d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    ageDay   = (milli / (24*60*60*1000));
2484d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                }
2494d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                sbuf.append("{").append(result.BSSID).append(",").append(result.frequency);
2504d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                sbuf.append(",").append(String.format("%3d", result.level));
2514d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                if (result.autoJoinStatus > 0) {
2524d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    sbuf.append(",st=").append(result.autoJoinStatus);
2534d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                }
2544d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                if (ageSec > 0 || ageMilli > 0) {
2554d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    sbuf.append(String.format(",%4d.%02d.%02d.%02d.%03dms", ageDay,
2564d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                            ageHour, ageMin, ageSec, ageMilli));
2574d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                }
2584d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                if (result.numIpConfigFailures > 0) {
2594d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    sbuf.append(",ipfail=");
2604d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    sbuf.append(result.numIpConfigFailures);
2614d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                }
2624d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                sbuf.append("} ");
2634d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            }
2644d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            sbuf.append('\n');
2654d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        }
2664d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
2674d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        return sbuf.toString();
2684d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    }
2694d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
2704d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande}
271