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