ScanDetail.java revision b3c9b82f86637a6bc0a9e442ee759bd4eb5d8ad0
1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.wifi; 18 19import android.net.wifi.AnqpInformationElement; 20import android.net.wifi.ScanResult; 21import android.net.wifi.WifiSsid; 22 23import com.android.server.wifi.anqp.ANQPElement; 24import com.android.server.wifi.anqp.Constants; 25import com.android.server.wifi.anqp.HSFriendlyNameElement; 26import com.android.server.wifi.anqp.RawByteElement; 27import com.android.server.wifi.anqp.VenueNameElement; 28import com.android.server.wifi.hotspot2.NetworkDetail; 29import com.android.server.wifi.hotspot2.PasspointMatch; 30import com.android.server.wifi.hotspot2.PasspointMatchInfo; 31import com.android.server.wifi.hotspot2.Utils; 32import com.android.server.wifi.hotspot2.pps.HomeSP; 33 34import java.util.ArrayList; 35import java.util.List; 36import java.util.Map; 37 38/** 39 * Wifi scan result details. 40 */ 41public class ScanDetail { 42 private final ScanResult mScanResult; 43 private volatile NetworkDetail mNetworkDetail; 44 private final Map<HomeSP, PasspointMatch> mMatches; 45 private long mSeen = 0; 46 47 public ScanDetail(NetworkDetail networkDetail, WifiSsid wifiSsid, String bssid, 48 String caps, int level, int frequency, long tsf, 49 ScanResult.InformationElement[] informationElements, List<String> anqpLines) { 50 mNetworkDetail = networkDetail; 51 mScanResult = new ScanResult(wifiSsid, bssid, networkDetail.getHESSID(), 52 networkDetail.getAnqpDomainID(), networkDetail.getOsuProviders(), 53 caps, level, frequency, tsf); 54 mSeen = System.currentTimeMillis(); 55 //mScanResult.seen = mSeen; 56 mScanResult.channelWidth = networkDetail.getChannelWidth(); 57 mScanResult.centerFreq0 = networkDetail.getCenterfreq0(); 58 mScanResult.centerFreq1 = networkDetail.getCenterfreq1(); 59 mScanResult.informationElements = informationElements; 60 mScanResult.anqpLines = anqpLines; 61 if (networkDetail.is80211McResponderSupport()) { 62 mScanResult.setFlag(ScanResult.FLAG_80211mc_RESPONDER); 63 } 64 mMatches = null; 65 } 66 67 public ScanDetail(WifiSsid wifiSsid, String bssid, String caps, int level, int frequency, 68 long tsf, long seen) { 69 mNetworkDetail = null; 70 mScanResult = new ScanResult(wifiSsid, bssid, 0L, -1, null, caps, level, frequency, tsf); 71 mSeen = seen; 72 //mScanResult.seen = mSeen; 73 mScanResult.channelWidth = 0; 74 mScanResult.centerFreq0 = 0; 75 mScanResult.centerFreq1 = 0; 76 mScanResult.flags = 0; 77 mMatches = null; 78 } 79 80 public ScanDetail(ScanResult scanResult, NetworkDetail networkDetail, 81 Map<HomeSP, PasspointMatch> matches) { 82 mScanResult = scanResult; 83 mNetworkDetail = networkDetail; 84 mMatches = matches; 85 } 86 87 /** 88 * Update the data stored in the scan result with the provided information. 89 * 90 * @param networkDetail NetworkDetail 91 * @param level int 92 * @param wssid WifiSsid 93 * @param ssid String 94 * @param flags String 95 * @param freq int 96 * @param tsf long 97 */ 98 public void updateResults(NetworkDetail networkDetail, int level, WifiSsid wssid, String ssid, 99 String flags, int freq, long tsf) { 100 mScanResult.level = level; 101 mScanResult.wifiSsid = wssid; 102 // Keep existing API 103 mScanResult.SSID = ssid; 104 mScanResult.capabilities = flags; 105 mScanResult.frequency = freq; 106 mScanResult.timestamp = tsf; 107 mSeen = System.currentTimeMillis(); 108 //mScanResult.seen = mSeen; 109 mScanResult.channelWidth = networkDetail.getChannelWidth(); 110 mScanResult.centerFreq0 = networkDetail.getCenterfreq0(); 111 mScanResult.centerFreq1 = networkDetail.getCenterfreq1(); 112 if (networkDetail.is80211McResponderSupport()) { 113 mScanResult.setFlag(ScanResult.FLAG_80211mc_RESPONDER); 114 } 115 if (networkDetail.isInterworking()) { 116 mScanResult.setFlag(ScanResult.FLAG_PASSPOINT_NETWORK); 117 } 118 } 119 120 /** 121 * Store ANQ element information 122 * 123 * @param anqpElements Map<Constants.ANQPElementType, ANQPElement> 124 */ 125 public void propagateANQPInfo(Map<Constants.ANQPElementType, ANQPElement> anqpElements) { 126 if (anqpElements.isEmpty()) { 127 return; 128 } 129 mNetworkDetail = mNetworkDetail.complete(anqpElements); 130 HSFriendlyNameElement fne = (HSFriendlyNameElement) anqpElements.get( 131 Constants.ANQPElementType.HSFriendlyName); 132 // !!! Match with language 133 if (fne != null && !fne.getNames().isEmpty()) { 134 mScanResult.venueName = fne.getNames().get(0).getText(); 135 } else { 136 VenueNameElement vne = 137 (((VenueNameElement) anqpElements.get( 138 Constants.ANQPElementType.ANQPVenueName))); 139 if (vne != null && !vne.getNames().isEmpty()) { 140 mScanResult.venueName = vne.getNames().get(0).getText(); 141 } 142 } 143 RawByteElement osuProviders = (RawByteElement) anqpElements 144 .get(Constants.ANQPElementType.HSOSUProviders); 145 if (osuProviders != null) { 146 mScanResult.anqpElements = new AnqpInformationElement[1]; 147 mScanResult.anqpElements[0] = 148 new AnqpInformationElement(AnqpInformationElement.HOTSPOT20_VENDOR_ID, 149 AnqpInformationElement.HS_OSU_PROVIDERS, osuProviders.getPayload()); 150 } 151 } 152 153 /** 154 * Return the scan result bject. 155 * 156 * @return ScanResult 157 */ 158 public ScanResult getScanResult() { 159 return mScanResult; 160 } 161 162 /** 163 * Return current network detail object 164 * 165 * @return NetworkDetail 166 */ 167 public NetworkDetail getNetworkDetail() { 168 return mNetworkDetail; 169 } 170 171 /** 172 * Return the associated ssid 173 * 174 * @return String 175 */ 176 public String getSSID() { 177 return mNetworkDetail == null ? mScanResult.SSID : mNetworkDetail.getSSID(); 178 } 179 180 /** 181 * Return the associated bssid String 182 * 183 * @return String bssid 184 */ 185 public String getBSSIDString() { 186 return mNetworkDetail == null ? mScanResult.BSSID : mNetworkDetail.getBSSIDString(); 187 } 188 189 /** 190 * Return the network detail key string. 191 * 192 * @return String 193 */ 194 public String toKeyString() { 195 NetworkDetail networkDetail = mNetworkDetail; 196 if (networkDetail != null) { 197 return networkDetail.toKeyString(); 198 } else { 199 return String.format("'%s':%012x", 200 mScanResult.BSSID, 201 Utils.parseMac(mScanResult.BSSID)); 202 } 203 } 204 205 /** 206 * Return the time this network was last seen. 207 * 208 * @return long 209 */ 210 public long getSeen() { 211 return mSeen; 212 } 213 214 /** 215 * Update the time this network was last seen to the current system time. 216 * 217 * @return long 218 */ 219 public long setSeen() { 220 mSeen = System.currentTimeMillis(); 221 mScanResult.seen = mSeen; 222 return mSeen; 223 } 224 225 @Override 226 public String toString() { 227 try { 228 return String.format("'%s'/%012x", 229 mScanResult.SSID, 230 Utils.parseMac(mScanResult.BSSID)); 231 } catch (IllegalArgumentException iae) { 232 return String.format("'%s'/----", mScanResult.BSSID); 233 } 234 } 235} 236