Home | History | Annotate | Download | only in hotspot2
      1 /*
      2  * Copyright (C) 2016 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.hotspot2;
     18 
     19 import android.util.Log;
     20 import android.util.Pair;
     21 
     22 import com.android.server.wifi.WifiNative;
     23 import com.android.server.wifi.hotspot2.anqp.ANQPElement;
     24 import com.android.server.wifi.hotspot2.anqp.Constants;
     25 
     26 import java.util.HashSet;
     27 import java.util.List;
     28 import java.util.Map;
     29 import java.util.Set;
     30 
     31 /**
     32  * This class handles passpoint specific interactions with the AP, such as ANQP
     33  * elements requests, passpoint icon requests, and wireless network management
     34  * event notifications.
     35  */
     36 public class PasspointEventHandler {
     37     private final WifiNative mSupplicantHook;
     38     private final Callbacks mCallbacks;
     39 
     40     /**
     41      * Interface to be implemented by the client to receive callbacks for passpoint
     42      * related events.
     43      */
     44     public interface Callbacks {
     45         /**
     46          * Invoked on received of ANQP response. |anqpElements| will be null on failure.
     47          * @param bssid BSSID of the AP
     48          * @param anqpElements ANQP elements to be queried
     49          */
     50         void onANQPResponse(long bssid,
     51                             Map<Constants.ANQPElementType, ANQPElement> anqpElements);
     52 
     53         /**
     54          * Invoked on received of icon response. |filename| and |data| will be null
     55          * on failure.
     56          * @param bssid BSSID of the AP
     57          * @param filename Name of the icon file
     58          * @data icon data bytes
     59          */
     60         void onIconResponse(long bssid, String filename, byte[] data);
     61 
     62         /**
     63          * Invoked on received of Hotspot 2.0 Wireless Network Management frame.
     64          * @param data Wireless Network Management frame data
     65          */
     66         void onWnmFrameReceived(WnmData data);
     67     }
     68 
     69     public PasspointEventHandler(WifiNative supplicantHook, Callbacks callbacks) {
     70         mSupplicantHook = supplicantHook;
     71         mCallbacks = callbacks;
     72     }
     73 
     74     /**
     75      * Request the specified ANQP elements |elements| from the specified AP |bssid|.
     76      * @param bssid BSSID of the AP
     77      * @param elements ANQP elements to be queried
     78      * @return true if request is sent successfully, false otherwise.
     79      */
     80     public boolean requestANQP(long bssid, List<Constants.ANQPElementType> elements) {
     81         Pair<Set<Integer>, Set<Integer>> querySets = buildAnqpIdSet(elements);
     82         if (bssid == 0 || querySets == null) return false;
     83         if (!mSupplicantHook.requestAnqp(
     84                 mSupplicantHook.getClientInterfaceName(),
     85                 Utils.macToString(bssid), querySets.first, querySets.second)) {
     86             Log.d(Utils.hs2LogTag(getClass()), "ANQP failed on " + Utils.macToString(bssid));
     87             return false;
     88         }
     89         Log.d(Utils.hs2LogTag(getClass()), "ANQP initiated on " + Utils.macToString(bssid));
     90         return true;
     91     }
     92 
     93     /**
     94      * Request a passpoint icon file |filename| from the specified AP |bssid|.
     95      * @param bssid BSSID of the AP
     96      * @param fileName name of the icon file
     97      * @return true if request is sent successfully, false otherwise
     98      */
     99     public boolean requestIcon(long bssid, String fileName) {
    100         if (bssid == 0 || fileName == null) return false;
    101         return mSupplicantHook.requestIcon(
    102                 mSupplicantHook.getClientInterfaceName(), Utils.macToString(bssid), fileName);
    103     }
    104 
    105     /**
    106      * Invoked when ANQP query is completed.
    107      * TODO(zqiu): currently ANQP completion notification is through WifiMonitor,
    108      * this shouldn't be needed once we switch over to wificond for ANQP requests.
    109      * @param anqpEvent ANQP result data retrieved. ANQP elements could be empty in the event to
    110      *                  indicate any failures.
    111      */
    112     public void notifyANQPDone(AnqpEvent anqpEvent) {
    113         if (anqpEvent == null) return;
    114         mCallbacks.onANQPResponse(anqpEvent.getBssid(), anqpEvent.getElements());
    115     }
    116 
    117     /**
    118      * Invoked when icon query is completed.
    119      * TODO(zqiu): currently icon completion notification is through WifiMonitor,
    120      * this shouldn't be needed once we switch over to wificond for icon requests.
    121      * @param iconEvent icon event data
    122      */
    123     public void notifyIconDone(IconEvent iconEvent) {
    124         if (iconEvent == null) return;
    125         mCallbacks.onIconResponse(
    126                 iconEvent.getBSSID(), iconEvent.getFileName(), iconEvent.getData());
    127     }
    128 
    129     /**
    130      * Invoked when a Wireless Network Management (WNM) frame is received.
    131      * TODO(zqiu): currently WNM frame notification is through WifiMonitor,
    132      * this shouldn't be needed once we switch over to wificond for WNM frame monitoring.
    133      * @param data WNM frame data
    134      */
    135     public void notifyWnmFrameReceived(WnmData data) {
    136         mCallbacks.onWnmFrameReceived(data);
    137     }
    138 
    139     /**
    140      * Create the set of ANQP ID's to query.
    141      *
    142      * @param querySet elements to query
    143      * @return Pair of <set of ANQP ID's, set of HS20 subtypes>
    144      */
    145     private static Pair<Set<Integer>, Set<Integer>> buildAnqpIdSet(
    146             List<Constants.ANQPElementType> querySet) {
    147         Set<Integer> anqpIds = new HashSet<>();
    148         Set<Integer> hs20Subtypes = new HashSet<>();
    149         for (Constants.ANQPElementType elementType : querySet) {
    150             Integer id = Constants.getANQPElementID(elementType);
    151             if (id != null) {
    152                 anqpIds.add(id);
    153             } else {
    154                 id = Constants.getHS20ElementID(elementType);
    155                 hs20Subtypes.add(id);
    156             }
    157         }
    158         return Pair.create(anqpIds, hs20Subtypes);
    159     }
    160 
    161 }
    162