blob: 3815c30b05403e3db47a588778f932f194ef1780 [file] [log] [blame]
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.wifi.hotspot2;
import android.util.Log;
import android.util.Pair;
import com.android.server.wifi.WifiNative;
import com.android.server.wifi.hotspot2.anqp.ANQPElement;
import com.android.server.wifi.hotspot2.anqp.Constants;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* This class handles passpoint specific interactions with the AP, such as ANQP
* elements requests, passpoint icon requests, and wireless network management
* event notifications.
*/
public class PasspointEventHandler {
private final WifiNative mSupplicantHook;
private final Callbacks mCallbacks;
/**
* Interface to be implemented by the client to receive callbacks for passpoint
* related events.
*/
public interface Callbacks {
/**
* Invoked on received of ANQP response. |anqpElements| will be null on failure.
* @param bssid BSSID of the AP
* @param anqpElements ANQP elements to be queried
*/
void onANQPResponse(long bssid,
Map<Constants.ANQPElementType, ANQPElement> anqpElements);
/**
* Invoked on received of icon response. |filename| and |data| will be null
* on failure.
* @param bssid BSSID of the AP
* @param filename Name of the icon file
* @data icon data bytes
*/
void onIconResponse(long bssid, String filename, byte[] data);
/**
* Invoked on received of Hotspot 2.0 Wireless Network Management frame.
* @param data Wireless Network Management frame data
*/
void onWnmFrameReceived(WnmData data);
}
public PasspointEventHandler(WifiNative supplicantHook, Callbacks callbacks) {
mSupplicantHook = supplicantHook;
mCallbacks = callbacks;
}
/**
* Request the specified ANQP elements |elements| from the specified AP |bssid|.
* @param bssid BSSID of the AP
* @param elements ANQP elements to be queried
* @return true if request is sent successfully, false otherwise.
*/
public boolean requestANQP(long bssid, List<Constants.ANQPElementType> elements) {
Pair<Set<Integer>, Set<Integer>> querySets = buildAnqpIdSet(elements);
if (bssid == 0 || querySets == null) return false;
if (!mSupplicantHook.requestAnqp(
mSupplicantHook.getClientInterfaceName(),
Utils.macToString(bssid), querySets.first, querySets.second)) {
Log.d(Utils.hs2LogTag(getClass()), "ANQP failed on " + Utils.macToString(bssid));
return false;
}
Log.d(Utils.hs2LogTag(getClass()), "ANQP initiated on " + Utils.macToString(bssid));
return true;
}
/**
* Request a passpoint icon file |filename| from the specified AP |bssid|.
* @param bssid BSSID of the AP
* @param fileName name of the icon file
* @return true if request is sent successfully, false otherwise
*/
public boolean requestIcon(long bssid, String fileName) {
if (bssid == 0 || fileName == null) return false;
return mSupplicantHook.requestIcon(
mSupplicantHook.getClientInterfaceName(), Utils.macToString(bssid), fileName);
}
/**
* Invoked when ANQP query is completed.
* TODO(zqiu): currently ANQP completion notification is through WifiMonitor,
* this shouldn't be needed once we switch over to wificond for ANQP requests.
* @param anqpEvent ANQP result data retrieved. ANQP elements could be empty in the event to
* indicate any failures.
*/
public void notifyANQPDone(AnqpEvent anqpEvent) {
if (anqpEvent == null) return;
mCallbacks.onANQPResponse(anqpEvent.getBssid(), anqpEvent.getElements());
}
/**
* Invoked when icon query is completed.
* TODO(zqiu): currently icon completion notification is through WifiMonitor,
* this shouldn't be needed once we switch over to wificond for icon requests.
* @param iconEvent icon event data
*/
public void notifyIconDone(IconEvent iconEvent) {
if (iconEvent == null) return;
mCallbacks.onIconResponse(
iconEvent.getBSSID(), iconEvent.getFileName(), iconEvent.getData());
}
/**
* Invoked when a Wireless Network Management (WNM) frame is received.
* TODO(zqiu): currently WNM frame notification is through WifiMonitor,
* this shouldn't be needed once we switch over to wificond for WNM frame monitoring.
* @param data WNM frame data
*/
public void notifyWnmFrameReceived(WnmData data) {
mCallbacks.onWnmFrameReceived(data);
}
/**
* Create the set of ANQP ID's to query.
*
* @param querySet elements to query
* @return Pair of <set of ANQP ID's, set of HS20 subtypes>
*/
private static Pair<Set<Integer>, Set<Integer>> buildAnqpIdSet(
List<Constants.ANQPElementType> querySet) {
Set<Integer> anqpIds = new HashSet<>();
Set<Integer> hs20Subtypes = new HashSet<>();
for (Constants.ANQPElementType elementType : querySet) {
Integer id = Constants.getANQPElementID(elementType);
if (id != null) {
anqpIds.add(id);
} else {
id = Constants.getHS20ElementID(elementType);
hs20Subtypes.add(id);
}
}
return Pair.create(anqpIds, hs20Subtypes);
}
}