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