Home | History | Annotate | Download | only in wifi
      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.anqp.ANQPElement;
     24 import com.android.server.wifi.anqp.Constants;
     25 import com.android.server.wifi.anqp.HSFriendlyNameElement;
     26 import com.android.server.wifi.anqp.RawByteElement;
     27 import com.android.server.wifi.anqp.VenueNameElement;
     28 import com.android.server.wifi.hotspot2.NetworkDetail;
     29 import com.android.server.wifi.hotspot2.PasspointMatch;
     30 import com.android.server.wifi.hotspot2.Utils;
     31 import com.android.server.wifi.hotspot2.pps.HomeSP;
     32 
     33 import java.util.List;
     34 import java.util.Map;
     35 
     36 /**
     37  * Wifi scan result details.
     38  */
     39 public class ScanDetail {
     40     private final ScanResult mScanResult;
     41     private volatile NetworkDetail mNetworkDetail;
     42     private final Map<HomeSP, PasspointMatch> mMatches;
     43     private long mSeen = 0;
     44 
     45     public ScanDetail(NetworkDetail networkDetail, WifiSsid wifiSsid, String bssid,
     46             String caps, int level, int frequency, long tsf,
     47             ScanResult.InformationElement[] informationElements, List<String> anqpLines) {
     48         mNetworkDetail = networkDetail;
     49         mScanResult = new ScanResult(wifiSsid, bssid, networkDetail.getHESSID(),
     50                 networkDetail.getAnqpDomainID(), networkDetail.getOsuProviders(),
     51                 caps, level, frequency, tsf);
     52         mSeen = System.currentTimeMillis();
     53         //mScanResult.seen = mSeen;
     54         mScanResult.channelWidth = networkDetail.getChannelWidth();
     55         mScanResult.centerFreq0 = networkDetail.getCenterfreq0();
     56         mScanResult.centerFreq1 = networkDetail.getCenterfreq1();
     57         mScanResult.informationElements = informationElements;
     58         mScanResult.anqpLines = anqpLines;
     59         if (networkDetail.is80211McResponderSupport()) {
     60             mScanResult.setFlag(ScanResult.FLAG_80211mc_RESPONDER);
     61         }
     62         if (networkDetail.isInterworking()) {
     63             mScanResult.setFlag(ScanResult.FLAG_PASSPOINT_NETWORK);
     64         }
     65         mMatches = null;
     66     }
     67 
     68     public ScanDetail(WifiSsid wifiSsid, String bssid, String caps, int level, int frequency,
     69                       long tsf, long seen) {
     70         mNetworkDetail = null;
     71         mScanResult = new ScanResult(wifiSsid, bssid, 0L, -1, null, caps, level, frequency, tsf);
     72         mSeen = seen;
     73         //mScanResult.seen = mSeen;
     74         mScanResult.channelWidth = 0;
     75         mScanResult.centerFreq0 = 0;
     76         mScanResult.centerFreq1 = 0;
     77         mScanResult.flags = 0;
     78         mMatches = null;
     79     }
     80 
     81     public ScanDetail(ScanResult scanResult, NetworkDetail networkDetail,
     82                        Map<HomeSP, PasspointMatch> matches) {
     83         mScanResult = scanResult;
     84         mNetworkDetail = networkDetail;
     85         mMatches = matches;
     86         mSeen = mScanResult.seen;
     87     }
     88 
     89     /**
     90      * Update the data stored in the scan result with the provided information.
     91      *
     92      * @param networkDetail NetworkDetail
     93      * @param level int
     94      * @param wssid WifiSsid
     95      * @param ssid String
     96      * @param flags String
     97      * @param freq int
     98      * @param tsf long
     99      */
    100     public void updateResults(NetworkDetail networkDetail, int level, WifiSsid wssid, String ssid,
    101                               String flags, int freq, long tsf) {
    102         mScanResult.level = level;
    103         mScanResult.wifiSsid = wssid;
    104         // Keep existing API
    105         mScanResult.SSID = ssid;
    106         mScanResult.capabilities = flags;
    107         mScanResult.frequency = freq;
    108         mScanResult.timestamp = tsf;
    109         mSeen = System.currentTimeMillis();
    110         //mScanResult.seen = mSeen;
    111         mScanResult.channelWidth = networkDetail.getChannelWidth();
    112         mScanResult.centerFreq0 = networkDetail.getCenterfreq0();
    113         mScanResult.centerFreq1 = networkDetail.getCenterfreq1();
    114         if (networkDetail.is80211McResponderSupport()) {
    115             mScanResult.setFlag(ScanResult.FLAG_80211mc_RESPONDER);
    116         }
    117         if (networkDetail.isInterworking()) {
    118             mScanResult.setFlag(ScanResult.FLAG_PASSPOINT_NETWORK);
    119         }
    120     }
    121 
    122     /**
    123      * Store ANQ element information
    124      *
    125      * @param anqpElements Map<Constants.ANQPElementType, ANQPElement>
    126      */
    127     public void propagateANQPInfo(Map<Constants.ANQPElementType, ANQPElement> anqpElements) {
    128         if (anqpElements.isEmpty()) {
    129             return;
    130         }
    131         mNetworkDetail = mNetworkDetail.complete(anqpElements);
    132         HSFriendlyNameElement fne = (HSFriendlyNameElement) anqpElements.get(
    133                 Constants.ANQPElementType.HSFriendlyName);
    134         // !!! Match with language
    135         if (fne != null && !fne.getNames().isEmpty()) {
    136             mScanResult.venueName = fne.getNames().get(0).getText();
    137         } else {
    138             VenueNameElement vne =
    139                     (((VenueNameElement) anqpElements.get(
    140                             Constants.ANQPElementType.ANQPVenueName)));
    141             if (vne != null && !vne.getNames().isEmpty()) {
    142                 mScanResult.venueName = vne.getNames().get(0).getText();
    143             }
    144         }
    145         RawByteElement osuProviders = (RawByteElement) anqpElements
    146                 .get(Constants.ANQPElementType.HSOSUProviders);
    147         if (osuProviders != null) {
    148             mScanResult.anqpElements = new AnqpInformationElement[1];
    149             mScanResult.anqpElements[0] =
    150                     new AnqpInformationElement(AnqpInformationElement.HOTSPOT20_VENDOR_ID,
    151                             AnqpInformationElement.HS_OSU_PROVIDERS, osuProviders.getPayload());
    152         }
    153     }
    154 
    155     public ScanResult getScanResult() {
    156         return mScanResult;
    157     }
    158 
    159     public NetworkDetail getNetworkDetail() {
    160         return mNetworkDetail;
    161     }
    162 
    163     public String getSSID() {
    164         return mNetworkDetail == null ? mScanResult.SSID : mNetworkDetail.getSSID();
    165     }
    166 
    167     public String getBSSIDString() {
    168         return  mNetworkDetail == null ? mScanResult.BSSID : mNetworkDetail.getBSSIDString();
    169     }
    170 
    171     /**
    172      *  Return the network detail key string.
    173      */
    174     public String toKeyString() {
    175         NetworkDetail networkDetail = mNetworkDetail;
    176         if (networkDetail != null) {
    177             return networkDetail.toKeyString();
    178         } else {
    179             return String.format("'%s':%012x",
    180                                  mScanResult.BSSID,
    181                                  Utils.parseMac(mScanResult.BSSID));
    182         }
    183     }
    184 
    185     /**
    186      * Return the time this network was last seen.
    187      */
    188     public long getSeen() {
    189         return mSeen;
    190     }
    191 
    192     /**
    193      * Update the time this network was last seen to the current system time.
    194      */
    195     public long setSeen() {
    196         mSeen = System.currentTimeMillis();
    197         mScanResult.seen = mSeen;
    198         return mSeen;
    199     }
    200 
    201     @Override
    202     public String toString() {
    203         try {
    204             return String.format("'%s'/%012x",
    205                                  mScanResult.SSID,
    206                                  Utils.parseMac(mScanResult.BSSID));
    207         } catch (IllegalArgumentException iae) {
    208             return String.format("'%s'/----", mScanResult.BSSID);
    209         }
    210     }
    211 }
    212