• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.android.server.wifi;
18 
19 import android.net.wifi.AnqpInformationElement;
20 import android.net.wifi.ScanResult;
21 import android.net.wifi.WifiSsid;
22 
23 import com.android.server.wifi.hotspot2.NetworkDetail;
24 import com.android.server.wifi.hotspot2.Utils;
25 import com.android.server.wifi.hotspot2.anqp.ANQPElement;
26 import com.android.server.wifi.hotspot2.anqp.Constants;
27 import com.android.server.wifi.hotspot2.anqp.HSFriendlyNameElement;
28 import com.android.server.wifi.hotspot2.anqp.RawByteElement;
29 import com.android.server.wifi.hotspot2.anqp.VenueNameElement;
30 
31 import java.util.List;
32 import java.util.Map;
33 
34 /**
35  * Wifi scan result details.
36  */
37 public class ScanDetail {
38     private final ScanResult mScanResult;
39     private volatile NetworkDetail mNetworkDetail;
40     private long mSeen = 0;
41     private byte[] mInformationElementRawData;
42 
ScanDetail(NetworkDetail networkDetail, WifiSsid wifiSsid, String bssid, String caps, int level, int frequency, long tsf, ScanResult.InformationElement[] informationElements, List<String> anqpLines, byte[] informationElementRawData)43     public ScanDetail(NetworkDetail networkDetail, WifiSsid wifiSsid, String bssid,
44             String caps, int level, int frequency, long tsf,
45             ScanResult.InformationElement[] informationElements, List<String> anqpLines,
46             byte[] informationElementRawData) {
47         mNetworkDetail = networkDetail;
48         mScanResult = new ScanResult(wifiSsid, bssid, networkDetail.getHESSID(),
49                 networkDetail.getAnqpDomainID(), networkDetail.getOsuProviders(),
50                 caps, level, frequency, tsf);
51         mSeen = System.currentTimeMillis();
52         mScanResult.seen = mSeen;
53         mScanResult.channelWidth = networkDetail.getChannelWidth();
54         mScanResult.centerFreq0 = networkDetail.getCenterfreq0();
55         mScanResult.centerFreq1 = networkDetail.getCenterfreq1();
56         mScanResult.informationElements = informationElements;
57         mScanResult.anqpLines = anqpLines;
58         if (networkDetail.is80211McResponderSupport()) {
59             mScanResult.setFlag(ScanResult.FLAG_80211mc_RESPONDER);
60         }
61         if (networkDetail.isInterworking() && networkDetail.getHSRelease() != null) {
62             mScanResult.setFlag(ScanResult.FLAG_PASSPOINT_NETWORK);
63         }
64         mInformationElementRawData = informationElementRawData;
65     }
66 
ScanDetail(WifiSsid wifiSsid, String bssid, String caps, int level, int frequency, long tsf, long seen)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     }
78 
ScanDetail(ScanResult scanResult, NetworkDetail networkDetail)79     public ScanDetail(ScanResult scanResult, NetworkDetail networkDetail) {
80         mScanResult = scanResult;
81         mNetworkDetail = networkDetail;
82         // Only inherit |mScanResult.seen| if it was previously set. This ensures that |mSeen|
83         // will always contain a valid timestamp.
84         mSeen = (mScanResult.seen == 0) ? System.currentTimeMillis() : mScanResult.seen;
85     }
86 
87     /**
88      * Store ANQ element information
89      *
90      * @param anqpElements Map<Constants.ANQPElementType, ANQPElement>
91      */
propagateANQPInfo(Map<Constants.ANQPElementType, ANQPElement> anqpElements)92     public void propagateANQPInfo(Map<Constants.ANQPElementType, ANQPElement> anqpElements) {
93         if (anqpElements.isEmpty()) {
94             return;
95         }
96         mNetworkDetail = mNetworkDetail.complete(anqpElements);
97         HSFriendlyNameElement fne = (HSFriendlyNameElement) anqpElements.get(
98                 Constants.ANQPElementType.HSFriendlyName);
99         // !!! Match with language
100         if (fne != null && !fne.getNames().isEmpty()) {
101             mScanResult.venueName = fne.getNames().get(0).getText();
102         } else {
103             VenueNameElement vne =
104                     (((VenueNameElement) anqpElements.get(
105                             Constants.ANQPElementType.ANQPVenueName)));
106             if (vne != null && !vne.getNames().isEmpty()) {
107                 mScanResult.venueName = vne.getNames().get(0).getText();
108             }
109         }
110         RawByteElement osuProviders = (RawByteElement) anqpElements
111                 .get(Constants.ANQPElementType.HSOSUProviders);
112         if (osuProviders != null) {
113             mScanResult.anqpElements = new AnqpInformationElement[1];
114             mScanResult.anqpElements[0] =
115                     new AnqpInformationElement(AnqpInformationElement.HOTSPOT20_VENDOR_ID,
116                             AnqpInformationElement.HS_OSU_PROVIDERS, osuProviders.getPayload());
117         }
118     }
119 
getScanResult()120     public ScanResult getScanResult() {
121         return mScanResult;
122     }
123 
getNetworkDetail()124     public NetworkDetail getNetworkDetail() {
125         return mNetworkDetail;
126     }
127 
getSSID()128     public String getSSID() {
129         return mNetworkDetail == null ? mScanResult.SSID : mNetworkDetail.getSSID();
130     }
131 
getBSSIDString()132     public String getBSSIDString() {
133         return  mNetworkDetail == null ? mScanResult.BSSID : mNetworkDetail.getBSSIDString();
134     }
135 
136     /**
137      *  Return the network detail key string.
138      */
toKeyString()139     public String toKeyString() {
140         NetworkDetail networkDetail = mNetworkDetail;
141         if (networkDetail != null) {
142             return networkDetail.toKeyString();
143         } else {
144             return String.format("'%s':%012x",
145                                  mScanResult.BSSID,
146                                  Utils.parseMac(mScanResult.BSSID));
147         }
148     }
149 
150     /**
151      * Return the time this network was last seen.
152      */
getSeen()153     public long getSeen() {
154         return mSeen;
155     }
156 
157     /**
158      * Update the time this network was last seen to the current system time.
159      */
setSeen()160     public long setSeen() {
161         mSeen = System.currentTimeMillis();
162         mScanResult.seen = mSeen;
163         return mSeen;
164     }
165 
166     /**
167      * Return the network information element raw data.
168      */
getInformationElementRawData()169     public byte[] getInformationElementRawData() {
170         return mInformationElementRawData;
171     }
172 
173     @Override
toString()174     public String toString() {
175         try {
176             return String.format("'%s'/%012x",
177                                  mScanResult.SSID,
178                                  Utils.parseMac(mScanResult.BSSID));
179         } catch (IllegalArgumentException iae) {
180             return String.format("'%s'/----", mScanResult.BSSID);
181         }
182     }
183 }
184