diff options
author | Roshan Pius <rpius@google.com> | 2017-02-15 15:32:45 -0800 |
---|---|---|
committer | Roshan Pius <rpius@google.com> | 2017-02-16 10:19:15 -0800 |
commit | 773ef3483e18f1afbd9cdce1564add3d89cb21fa (patch) | |
tree | d34c29cfabd2f3c478251917675aed8a5ed9e189 /service/java | |
parent | 65d8ba5dd551cd132789e8feb270dfc7998dfbdc (diff) | |
download | android_frameworks_opt_net_wifi-773ef3483e18f1afbd9cdce1564add3d89cb21fa.tar.gz android_frameworks_opt_net_wifi-773ef3483e18f1afbd9cdce1564add3d89cb21fa.tar.bz2 android_frameworks_opt_net_wifi-773ef3483e18f1afbd9cdce1564add3d89cb21fa.zip |
Passpoint: Change ICON response handling
Currently, the ICON done notification from WifiMonitor is used
as a trigger to fetch icon data in PasspointEventHandler.
In the HIDL interface, the callback itself will contain all the
necessary icon data. So, change the currently handling to prepare for
integration with HIDL interface.
Changes in the CL:
1. Move the icon data fetching to WifiMonitor away from
PasspointEventHandler.
2. Change the params of the icon done event to include the icon data.
3. Add a new public method in WifiMonitor to send the notification out
from WifiMonitor, which will be used by the HIDL interface in the
future.
Note: There are no unit tests for any of these changes because this CL
is just moving things around and most of it is going to be removed when
we integrate with HIDL.
Bug: 35393853
Test: Connects to passpoint networks.
Test: Will send for regression tests.
Change-Id: I197180c8a8ec8673e5e8fa29ba8bb51b026d44fb
Diffstat (limited to 'service/java')
5 files changed, 84 insertions, 71 deletions
diff --git a/service/java/com/android/server/wifi/WifiMonitor.java b/service/java/com/android/server/wifi/WifiMonitor.java index 29bb1247c..22f59d72a 100644 --- a/service/java/com/android/server/wifi/WifiMonitor.java +++ b/service/java/com/android/server/wifi/WifiMonitor.java @@ -30,6 +30,7 @@ import android.os.Handler; import android.os.Message; import android.text.TextUtils; import android.util.ArraySet; +import android.util.Base64; import android.util.LocalLog; import android.util.Log; import android.util.SparseArray; @@ -532,6 +533,11 @@ public class WifiMonitor { public static final int AUTHENTICATION_FAILURE_REASON_WRONG_PSWD = 2; public static final int AUTHENTICATION_FAILURE_REASON_EAP_FAILURE = 3; + /** + * Used for icon retrieval. + */ + private static final int ICON_CHUNK_SIZE = 1400; // 2K*3/4 - overhead + // Singleton instance private static WifiMonitor sWifiMonitor = new WifiMonitor(); public static WifiMonitor getInstance() { @@ -1297,14 +1303,66 @@ public class WifiMonitor { String bssid = segments[1]; String fileName = segments[2]; int size = Integer.parseInt(segments[3]); - sendMessage(iface, RX_HS20_ANQP_ICON_EVENT, - new IconEvent(Utils.parseMac(bssid), fileName, size)); + byte[] iconData = null; + if (!TextUtils.isEmpty(bssid) && !TextUtils.isEmpty(fileName) && size > 0) { + try { + iconData = retrieveIcon(Utils.parseMac(bssid), fileName, size); + } catch (IOException ioe) { + Log.e(TAG, "Failed to retrieve icon: " + ioe.toString() + ": " + fileName); + } + } + broadcastIconDoneEvent( + iface, new IconEvent(Utils.parseMac(bssid), fileName, size, iconData)); } catch (NumberFormatException nfe) { throw new IllegalArgumentException("Bad numeral"); } } + // Retrieve the icon data from wpa_supplicant. + private byte[] retrieveIcon(long bssid, String fileName, int fileSize) throws IOException { + byte[] iconData = new byte[fileSize]; + try { + int offset = 0; + while (offset < fileSize) { + int size = Math.min(fileSize - offset, ICON_CHUNK_SIZE); + + String command = String.format("GET_HS20_ICON %s %s %d %d", + Utils.macToString(bssid), fileName, offset, size); + Log.d(TAG, "Issuing '" + command + "'"); + String response = mWifiNative.doCustomSupplicantCommand(command); + if (response == null) { + throw new IOException("No icon data returned"); + } + + try { + byte[] fragment = Base64.decode(response, Base64.DEFAULT); + if (fragment.length == 0) { + throw new IOException("Null data for '" + command + "': " + response); + } + if (fragment.length + offset > iconData.length) { + throw new IOException("Icon chunk exceeds image size"); + } + System.arraycopy(fragment, 0, iconData, offset, fragment.length); + offset += fragment.length; + } catch (IllegalArgumentException iae) { + throw new IOException("Failed to parse response to '" + command + + "': " + response); + } + } + if (offset != fileSize) { + Log.w(TAG, "Partial icon data: " + offset + ", expected " + fileSize); + } + } finally { + // Delete the icon file in supplicant. + Log.d(TAG, "Deleting icon for " + fileName); + String result = mWifiNative.doCustomSupplicantCommand("DEL_HS20_ICON " + + Utils.macToString(bssid) + " " + fileName); + Log.d(TAG, "Result: " + result); + } + return iconData; + } + private void handleWnmFrame(String eventStr, String iface) { try { WnmData wnmData = WnmData.buildWnmData(eventStr); @@ -1547,4 +1605,14 @@ public class WifiMonitor { public void broadcastAnqpDoneEvent(String iface, AnqpEvent anqpEvent) { sendMessage(iface, ANQP_DONE_EVENT, anqpEvent); } + + /** + * Broadcast the Icon done event to all the handlers registered for this event. + * + * @param iface Name of iface on which this occurred. + * @param iconEvent Instance of IconEvent containing the icon data retrieved. + */ + public void broadcastIconDoneEvent(String iface, IconEvent iconEvent) { + sendMessage(iface, RX_HS20_ANQP_ICON_EVENT, iconEvent); + } } diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index e8f2bb1aa..9e9373096 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -4301,8 +4301,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss } case WifiMonitor.RX_HS20_ANQP_ICON_EVENT: // TODO(zqiu): remove this when switch over to wificond for icon requests. - IconEvent event = (IconEvent) message.obj; - mPasspointManager.notifyIconDone(event.getBSSID(), event); + mPasspointManager.notifyIconDone((IconEvent) message.obj); break; case WifiMonitor.HS20_REMEDIATION_EVENT: // TODO(zqiu): remove this when switch over to wificond for WNM frames diff --git a/service/java/com/android/server/wifi/hotspot2/IconEvent.java b/service/java/com/android/server/wifi/hotspot2/IconEvent.java index 69a3b27ec..406c03cd3 100644 --- a/service/java/com/android/server/wifi/hotspot2/IconEvent.java +++ b/service/java/com/android/server/wifi/hotspot2/IconEvent.java @@ -4,11 +4,13 @@ public class IconEvent { private final long mBSSID; private final String mFileName; private final int mSize; + private final byte[] mData; - public IconEvent(long bssid, String fileName, int size) { + public IconEvent(long bssid, String fileName, int size, byte[] data) { mBSSID = bssid; mFileName = fileName; mSize = size; + mData = data; } public long getBSSID() { @@ -23,6 +25,10 @@ public class IconEvent { return mSize; } + public byte[] getData() { + return mData; + } + @Override public String toString() { return "IconEvent: " + diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointEventHandler.java b/service/java/com/android/server/wifi/hotspot2/PasspointEventHandler.java index 2bf099a5b..a46a0e591 100644 --- a/service/java/com/android/server/wifi/hotspot2/PasspointEventHandler.java +++ b/service/java/com/android/server/wifi/hotspot2/PasspointEventHandler.java @@ -16,14 +16,12 @@ package com.android.server.wifi.hotspot2; -import android.util.Base64; import android.util.Log; import com.android.server.wifi.WifiNative; import com.android.server.wifi.hotspot2.anqp.ANQPElement; import com.android.server.wifi.hotspot2.anqp.Constants; -import java.io.IOException; import java.util.List; import java.util.Map; @@ -36,8 +34,6 @@ public class PasspointEventHandler { private final WifiNative mSupplicantHook; private final Callbacks mCallbacks; - private static final int ICON_CHUNK_SIZE = 1400; // 2K*3/4 - overhead - /** * Interface to be implemented by the client to receive callbacks for passpoint * related events. @@ -124,22 +120,12 @@ public class PasspointEventHandler { * 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 bssid BSSID of the AP * @param iconEvent icon event data */ - public void notifyIconDone(long bssid, IconEvent iconEvent) { - String filename = null; - byte[] data = null; - if (iconEvent != null) { - try { - data = retrieveIcon(iconEvent); - filename = iconEvent.getFileName(); - } catch (IOException ioe) { - Log.e(Utils.hs2LogTag(getClass()), "Failed to retrieve icon: " + - ioe.toString() + ": " + iconEvent.getFileName()); - } - } - mCallbacks.onIconResponse(bssid, filename, data); + public void notifyIconDone(IconEvent iconEvent) { + if (iconEvent == null) return; + mCallbacks.onIconResponse( + iconEvent.getBSSID(), iconEvent.getFileName(), iconEvent.getData()); } /** @@ -197,50 +183,4 @@ public class PasspointEventHandler { return sb.toString(); } - private byte[] retrieveIcon(IconEvent iconEvent) throws IOException { - byte[] iconData = new byte[iconEvent.getSize()]; - try { - int offset = 0; - while (offset < iconEvent.getSize()) { - int size = Math.min(iconEvent.getSize() - offset, ICON_CHUNK_SIZE); - - String command = String.format("GET_HS20_ICON %s %s %d %d", - Utils.macToString(iconEvent.getBSSID()), iconEvent.getFileName(), - offset, size); - Log.d(Utils.hs2LogTag(getClass()), "Issuing '" + command + "'"); - String response = mSupplicantHook.doCustomSupplicantCommand(command); - if (response == null) { - throw new IOException("No icon data returned"); - } - - try { - byte[] fragment = Base64.decode(response, Base64.DEFAULT); - if (fragment.length == 0) { - throw new IOException("Null data for '" + command + "': " + response); - } - if (fragment.length + offset > iconData.length) { - throw new IOException("Icon chunk exceeds image size"); - } - System.arraycopy(fragment, 0, iconData, offset, fragment.length); - offset += fragment.length; - } catch (IllegalArgumentException iae) { - throw new IOException("Failed to parse response to '" + command - + "': " + response); - } - } - if (offset != iconEvent.getSize()) { - Log.w(Utils.hs2LogTag(getClass()), "Partial icon data: " + offset + - ", expected " + iconEvent.getSize()); - } - } - finally { - // Delete the icon file in supplicant. - Log.d(Utils.hs2LogTag(getClass()), "Deleting icon for " + iconEvent); - String result = mSupplicantHook.doCustomSupplicantCommand("DEL_HS20_ICON " + - Utils.macToString(iconEvent.getBSSID()) + " " + iconEvent.getFileName()); - Log.d(Utils.hs2LogTag(getClass()), "Result: " + result); - } - - return iconData; - } } diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java index 82058023b..8a5d113bb 100644 --- a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java +++ b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java @@ -339,8 +339,8 @@ public class PasspointManager { * TODO(zqiu): currently the notification is done through WifiMonitor, * will no longer be the case once we switch over to use wificond. */ - public void notifyIconDone(long bssid, IconEvent iconEvent) { - mHandler.notifyIconDone(bssid, iconEvent); + public void notifyIconDone(IconEvent iconEvent) { + mHandler.notifyIconDone(iconEvent); } /** |