summaryrefslogtreecommitdiffstats
path: root/service/java/com/android/server/wifi/WifiMonitor.java
diff options
context:
space:
mode:
authorJan Nordqvist <jannq@google.com>2015-07-21 17:23:27 -0700
committerJan Nordqvist <jannq@google.com>2015-09-22 18:15:23 -0700
commit1d5cd3938f9191184cd9aea3059a3b62bf3a0372 (patch)
tree26059deb99f117754a07f8cfd4031fb9ee60de99 /service/java/com/android/server/wifi/WifiMonitor.java
parent4351eeda51e8c3763b456a5b402e3c433563382e (diff)
downloadandroid_frameworks_opt_net_wifi-1d5cd3938f9191184cd9aea3059a3b62bf3a0372.tar.gz
android_frameworks_opt_net_wifi-1d5cd3938f9191184cd9aea3059a3b62bf3a0372.tar.bz2
android_frameworks_opt_net_wifi-1d5cd3938f9191184cd9aea3059a3b62bf3a0372.zip
Hotspot 2.0 relase 2 first cut.
Policy provisioning. API methods. Timers for policy and remediation. Icon and friendly name checking. Channel bindings for EST. Change-Id: Ifa7125743ea93d7d4329cb53fd70c99b9b06fffe
Diffstat (limited to 'service/java/com/android/server/wifi/WifiMonitor.java')
-rw-r--r--service/java/com/android/server/wifi/WifiMonitor.java110
1 files changed, 107 insertions, 3 deletions
diff --git a/service/java/com/android/server/wifi/WifiMonitor.java b/service/java/com/android/server/wifi/WifiMonitor.java
index 25eb02018..945901dfb 100644
--- a/service/java/com/android/server/wifi/WifiMonitor.java
+++ b/service/java/com/android/server/wifi/WifiMonitor.java
@@ -28,6 +28,7 @@ import android.net.wifi.p2p.WifiP2pProvDiscEvent;
import android.net.wifi.p2p.nsd.WifiP2pServiceResponse;
import android.os.Message;
import android.text.TextUtils;
+import android.util.Base64;
import android.util.LocalLog;
import android.util.Log;
@@ -38,7 +39,9 @@ import com.android.internal.util.Protocol;
import com.android.internal.util.StateMachine;
import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -114,8 +117,8 @@ public class WifiMonitor {
/* Hotspot 2.0 events */
private static final String HS20_PREFIX_STR = "HS20-";
- private static final String HS20_SUB_REM_STR = "HS20-SUBSCRIPTION-REMEDIATION";
- private static final String HS20_DEAUTH_STR = "HS20-DEAUTH-IMMINENT-NOTICE";
+ public static final String HS20_SUB_REM_STR = "HS20-SUBSCRIPTION-REMEDIATION";
+ public static final String HS20_DEAUTH_STR = "HS20-DEAUTH-IMMINENT-NOTICE";
private static final String IDENTITY_STR = "IDENTITY";
@@ -138,6 +141,9 @@ public class WifiMonitor {
* <code>xx:xx:xx:xx:xx:xx</code> is the BSSID of the associated access point
*/
private static final String CONNECTED_STR = "CONNECTED";
+ private static final String ConnectPrefix = "Connection to ";
+ private static final String ConnectSuffix = " completed";
+
/**
* <pre>
* CTRL-EVENT-DISCONNECTED - Disconnect event - remove keys
@@ -423,6 +429,7 @@ public class WifiMonitor {
/* AP-STA-DISCONNECTED 42:fc:89:a8:96:09 */
private static final String AP_STA_DISCONNECTED_STR = "AP-STA-DISCONNECTED";
private static final String ANQP_DONE_STR = "ANQP-QUERY-DONE";
+ private static final String HS20_ICON_STR = "RX-HS20-ICON";
/* Supplicant events reported to a state machine */
private static final int BASE = Protocol.BASE_WIFI_MONITOR;
@@ -771,6 +778,8 @@ public class WifiMonitor {
+" - "+ Thread.currentThread().getStackTrace()[5].getMethodName()*/);
}
+ private volatile long mLastConnectBSSID;
+
/* @return true if the event was supplicant disconnection */
private boolean dispatchEvent(String eventStr, String iface) {
@@ -805,6 +814,19 @@ public class WifiMonitor {
catch (IllegalArgumentException iae) {
Log.e(TAG, "Bad ANQP event string: '" + eventStr + "': " + iae);
}
+ } else if (eventStr.startsWith(HS20_ICON_STR)) {
+ try {
+ handleIconResult(eventStr);
+ }
+ catch (IllegalArgumentException iae) {
+ Log.e(TAG, "Bad Icon event string: '" + eventStr + "': " + iae);
+ }
+ }
+ else if (eventStr.startsWith(HS20_SUB_REM_STR)) {
+ // Tack on the last connected BSSID so we have some idea what AP the WNM pertains to
+ handleWnmRemediationFrame(String.format("%012x %s", mLastConnectBSSID, eventStr));
+ } else if (eventStr.startsWith(HS20_DEAUTH_STR)) {
+ handleWnmDeauthFrame(String.format("%012x %s", mLastConnectBSSID, eventStr));
} else if (eventStr.startsWith(REQUEST_PREFIX_STR)) {
handleRequests(eventStr);
} else if (eventStr.startsWith(TARGET_BSSID_STR)) {
@@ -834,8 +856,26 @@ public class WifiMonitor {
* Map event name into event enum
*/
int event;
- if (eventName.equals(CONNECTED_STR))
+ if (eventName.equals(CONNECTED_STR)) {
event = CONNECTED;
+ long bssid = -1L;
+ int prefix = eventStr.indexOf(ConnectPrefix);
+ if (prefix >= 0) {
+ int suffix = eventStr.indexOf(ConnectSuffix);
+ if (suffix > prefix) {
+ try {
+ bssid = Utils.parseMac(
+ eventStr.substring(prefix + ConnectPrefix.length(), suffix));
+ } catch (IllegalArgumentException iae) {
+ bssid = -1L;
+ }
+ }
+ }
+ mLastConnectBSSID = bssid;
+ if (bssid == -1L) {
+ Log.w(TAG, "Failed to parse out BSSID from '" + eventStr + "'");
+ }
+ }
else if (eventName.equals(DISCONNECTED_STR))
event = DISCONNECTED;
else if (eventName.equals(STATE_CHANGE_STR))
@@ -1216,6 +1256,70 @@ public class WifiMonitor {
}
}
+ private final Map<String, String[]> mIconFragmentMap = new LinkedHashMap<String, String[]>() {
+ @Override
+ protected boolean removeEldestEntry(Entry eldest) {
+ return size() > 3;
+ }
+ };
+
+ private void handleIconResult(String eventStr) {
+ // RX-HS20-ICON c0:c5:20:27:d1:e8 9 10 OMJjkpWlDpC+UC...
+ String[] segments = eventStr.split(" ");
+ if (segments.length != 5) {
+ throw new IllegalArgumentException("Incorrect number of segments");
+ }
+ try {
+ String bssid = segments[1];
+ int fragmentIndex = Integer.parseInt(segments[2]);
+ int fragmentEnd = Integer.parseInt(segments[3]);
+
+ String[] fragments = mIconFragmentMap.get(bssid);
+ if (fragments == null) {
+ fragments = new String[fragmentEnd+1];
+ mIconFragmentMap.put(bssid, fragments);
+ }
+ if (fragmentEnd >= fragments.length) {
+ fragments = new String[fragmentEnd+1];
+ mIconFragmentMap.put(bssid, fragments);
+ Log.w(TAG, String.format("Icon fragment %d out of %d exceeds %d",
+ fragmentIndex, fragmentEnd, fragments.length));
+ }
+ fragments[fragmentIndex] = segments[4];
+
+ boolean incomplete = false;
+ for (String fragment : fragments) {
+ if (fragment == null) {
+ incomplete = true;
+ break;
+ }
+ }
+ if (!incomplete) {
+ StringBuilder b64 = new StringBuilder();
+ for (String fragment : fragments) {
+ b64.append(fragment);
+ }
+ mIconFragmentMap.remove(bssid);
+ long mac = Utils.parseMac(bssid);
+ byte[] octets = Base64.decode(b64.toString(), Base64.DEFAULT);
+ mStateMachine.sendMessage(
+ RX_HS20_ANQP_ICON_EVENT, (int)(mac >>> 32), (int)mac, octets);
+ }
+ }
+ catch (NumberFormatException nfe) {
+ throw new IllegalArgumentException("Bad numeral");
+ }
+ }
+
+ private void handleWnmRemediationFrame(String eventStr) {
+ Log.d("ZXZ", "WNM frame: " + eventStr);
+ mStateMachine.sendMessage(HS20_REMEDIATION_EVENT, eventStr);
+ }
+
+ private void handleWnmDeauthFrame(String eventStr) {
+ mStateMachine.sendMessage(HS20_DEAUTH_EVENT, eventStr);
+ }
+
/**
* Handle Supplicant Requests
*/