1 package com.android.server.wifi; 2 3 import android.net.wifi.ScanResult; 4 import android.net.wifi.WifiSsid; 5 6 import com.android.server.wifi.anqp.ANQPElement; 7 import com.android.server.wifi.anqp.Constants; 8 import com.android.server.wifi.anqp.HSFriendlyNameElement; 9 import com.android.server.wifi.anqp.VenueNameElement; 10 import com.android.server.wifi.hotspot2.NetworkDetail; 11 import com.android.server.wifi.hotspot2.PasspointMatch; 12 import com.android.server.wifi.hotspot2.PasspointMatchInfo; 13 import com.android.server.wifi.hotspot2.Utils; 14 import com.android.server.wifi.hotspot2.pps.HomeSP; 15 16 import java.util.ArrayList; 17 import java.util.List; 18 import java.util.Map; 19 20 public class ScanDetail { 21 private final ScanResult mScanResult; 22 private volatile NetworkDetail mNetworkDetail; 23 private final Map<HomeSP, PasspointMatch> mMatches; 24 private long mSeen = 0; 25 ScanDetail(NetworkDetail networkDetail, WifiSsid wifiSsid, String BSSID, String caps, int level, int frequency, long tsf)26 public ScanDetail(NetworkDetail networkDetail, WifiSsid wifiSsid, String BSSID, 27 String caps, int level, int frequency, long tsf) { 28 mNetworkDetail = networkDetail; 29 mScanResult = new ScanResult(wifiSsid, BSSID, caps, level, frequency, tsf ); 30 mSeen = System.currentTimeMillis(); 31 //mScanResult.seen = mSeen; 32 mScanResult.channelWidth = networkDetail.getChannelWidth(); 33 mScanResult.centerFreq0 = networkDetail.getCenterfreq0(); 34 mScanResult.centerFreq1 = networkDetail.getCenterfreq1(); 35 if (networkDetail.is80211McResponderSupport()) 36 mScanResult.setFlag(ScanResult.FLAG_80211mc_RESPONDER); 37 mMatches = null; 38 } 39 ScanDetail(WifiSsid wifiSsid, String BSSID, String caps, int level, int frequency, long tsf, long seen)40 public ScanDetail(WifiSsid wifiSsid, String BSSID, String caps, int level, int frequency, 41 long tsf, long seen) { 42 mNetworkDetail = null; 43 mScanResult = new ScanResult(wifiSsid, BSSID, caps, level, frequency, tsf ); 44 mSeen = seen; 45 //mScanResult.seen = mSeen; 46 mScanResult.channelWidth = 0; 47 mScanResult.centerFreq0 = 0; 48 mScanResult.centerFreq1 = 0; 49 mScanResult.flags = 0; 50 mMatches = null; 51 } 52 ScanDetail(ScanResult scanResult, NetworkDetail networkDetail, Map<HomeSP, PasspointMatch> matches)53 private ScanDetail(ScanResult scanResult, NetworkDetail networkDetail, 54 Map<HomeSP, PasspointMatch> matches) { 55 mScanResult = scanResult; 56 mNetworkDetail = networkDetail; 57 mMatches = matches; 58 } 59 updateResults(NetworkDetail networkDetail, int level, WifiSsid wssid, String ssid, String flags, int freq, long tsf)60 public void updateResults(NetworkDetail networkDetail, int level, WifiSsid wssid, String ssid, 61 String flags, int freq, long tsf) { 62 mScanResult.level = level; 63 mScanResult.wifiSsid = wssid; 64 // Keep existing API 65 mScanResult.SSID = ssid; 66 mScanResult.capabilities = flags; 67 mScanResult.frequency = freq; 68 mScanResult.timestamp = tsf; 69 mSeen = System.currentTimeMillis(); 70 //mScanResult.seen = mSeen; 71 mScanResult.channelWidth = networkDetail.getChannelWidth(); 72 mScanResult.centerFreq0 = networkDetail.getCenterfreq0(); 73 mScanResult.centerFreq1 = networkDetail.getCenterfreq1(); 74 if (networkDetail.is80211McResponderSupport()) 75 mScanResult.setFlag(ScanResult.FLAG_80211mc_RESPONDER); 76 if (networkDetail.isInterworking()) 77 mScanResult.setFlag(ScanResult.FLAG_PASSPOINT_NETWORK); 78 } 79 propagateANQPInfo(Map<Constants.ANQPElementType, ANQPElement> anqpElements)80 public void propagateANQPInfo(Map<Constants.ANQPElementType, ANQPElement> anqpElements) { 81 if (anqpElements.isEmpty()) { 82 return; 83 } 84 mNetworkDetail = mNetworkDetail.complete(anqpElements); 85 HSFriendlyNameElement fne = (HSFriendlyNameElement)anqpElements.get( 86 Constants.ANQPElementType.HSFriendlyName); 87 // !!! Match with language 88 if (fne != null && !fne.getNames().isEmpty()) { 89 mScanResult.venueName = fne.getNames().get(0).getText(); 90 } else { 91 VenueNameElement vne = 92 (((VenueNameElement)anqpElements.get(Constants.ANQPElementType.ANQPVenueName))); 93 if (vne != null && !vne.getNames().isEmpty()) { 94 mScanResult.venueName = vne.getNames().get(0).getText(); 95 } 96 } 97 } 98 getScanResult()99 public ScanResult getScanResult() { 100 return mScanResult; 101 } 102 getNetworkDetail()103 public NetworkDetail getNetworkDetail() { 104 return mNetworkDetail; 105 } 106 getSSID()107 public String getSSID() { 108 return mNetworkDetail == null ? mScanResult.SSID : mNetworkDetail.getSSID(); 109 } 110 getBSSIDString()111 public String getBSSIDString() { 112 return mNetworkDetail == null ? mScanResult.BSSID : mNetworkDetail.getBSSIDString(); 113 } 114 toKeyString()115 public String toKeyString() { 116 NetworkDetail networkDetail = mNetworkDetail; 117 if (networkDetail != null) { 118 return networkDetail.toKeyString(); 119 } 120 else { 121 return String.format("'%s':%012x", mScanResult.BSSID, Utils.parseMac(mScanResult.BSSID)); 122 } 123 } 124 getSeen()125 public long getSeen() { 126 return mSeen; 127 } 128 setSeen()129 public long setSeen() { 130 mSeen = System.currentTimeMillis(); 131 mScanResult.seen = mSeen; 132 return mSeen; 133 } 134 getMatchList()135 public List<PasspointMatchInfo> getMatchList() { 136 if (mMatches == null || mMatches.isEmpty()) { 137 return null; 138 } 139 140 List<PasspointMatchInfo> list = new ArrayList<>(); 141 for (Map.Entry<HomeSP, PasspointMatch> entry : mMatches.entrySet()) { 142 new PasspointMatchInfo(entry.getValue(), this, entry.getKey()); 143 } 144 return list; 145 } 146 147 @Override toString()148 public String toString() { 149 try { 150 return String.format("'%s'/%012x", 151 mScanResult.SSID, Utils.parseMac(mScanResult.BSSID)); 152 } 153 catch (IllegalArgumentException iae) { 154 return String.format("'%s'/----", mScanResult.BSSID); 155 } 156 } 157 } 158