summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authorEtan Cohen <etancohen@google.com>2018-08-22 08:51:37 -0700
committerEtan Cohen <etancohen@google.com>2018-10-05 07:41:14 -0700
commitd71b53361125ea4f7340426c5e6c90bb10561dab (patch)
tree6b998d4f6de108f586884facf3f81b54e307bf7d /service
parent6d4cc3ccb1d19e3ee28ae31280ab0bc0bb068afd (diff)
[RTT] Handle HAL concurrencly limitations on RTT availability
The chip may not support RTT in all modes. The change handles this correctly: whenever the HAL cannot support RTT (e.g. for multi-mode chips + switching to AP mode only) the framework will be notified and can dispatch RTT availability notification to app (both when becoming non-available and then when becoming available again). This notification on exact status also fixes the following: - Initialization is precise: i.e. won't try to execute RTT commands on an as yet uninitialized chip - Can revert an early "hack" which re-tried creating a new RTT controller if the previous one simply stopped working Bug: 79565105 Bug: 111218083 Test: unit tests (new ones) Test: ACTS RangeApSupporting11McTest:test_rtt_in_and_after_softap_mode Change-Id: Ib9ef75bb679cdb0f49384260112c06684f52c693
Diffstat (limited to 'service')
-rw-r--r--service/java/com/android/server/wifi/HalDeviceManager.java242
-rw-r--r--service/java/com/android/server/wifi/WifiNative.java55
-rw-r--r--service/java/com/android/server/wifi/WifiVendorHal.java546
-rw-r--r--service/java/com/android/server/wifi/rtt/RttNative.java96
4 files changed, 254 insertions, 685 deletions
diff --git a/service/java/com/android/server/wifi/HalDeviceManager.java b/service/java/com/android/server/wifi/HalDeviceManager.java
index 3c61217d7..2acdc03e4 100644
--- a/service/java/com/android/server/wifi/HalDeviceManager.java
+++ b/service/java/com/android/server/wifi/HalDeviceManager.java
@@ -384,6 +384,49 @@ public class HalDeviceManager {
}
/**
+ * Register a callback object for RTT life-cycle events. The callback object registration
+ * indicates that an RTT controller should be created whenever possible. The callback object
+ * will be called with a new RTT controller whenever it is created (or at registration time
+ * if an RTT controller already exists). The callback object will also be triggered whenever
+ * an existing RTT controller is destroyed (the previous copies must be discarded by the
+ * recipient).
+ *
+ * @param callback InterfaceRttControllerLifecycleCallback object.
+ * @param handler Handler on which to dispatch callback
+ */
+ public void registerRttControllerLifecycleCallback(
+ @NonNull InterfaceRttControllerLifecycleCallback callback, @NonNull Handler handler) {
+ if (VDBG) {
+ Log.d(TAG, "registerRttControllerLifecycleCallback: callback=" + callback + ", handler="
+ + handler);
+ }
+
+ if (callback == null || handler == null) {
+ Log.wtf(TAG, "registerRttControllerLifecycleCallback with nulls!? callback=" + callback
+ + ", handler=" + handler);
+ return;
+ }
+
+ synchronized (mLock) {
+ InterfaceRttControllerLifecycleCallbackProxy proxy =
+ new InterfaceRttControllerLifecycleCallbackProxy(callback, handler);
+ if (!mRttControllerLifecycleCallbacks.add(proxy)) {
+ Log.d(TAG,
+ "registerRttControllerLifecycleCallback: registering an existing callback="
+ + callback);
+ return;
+ }
+
+ if (mIWifiRttController == null) {
+ mIWifiRttController = createRttControllerIfPossible();
+ }
+ if (mIWifiRttController != null) {
+ proxy.onNewRttController(mIWifiRttController);
+ }
+ }
+ }
+
+ /**
* Return the name of the input interface or null on error.
*/
public static String getName(IWifiIface iface) {
@@ -437,49 +480,31 @@ public class HalDeviceManager {
}
/**
- * Creates a IWifiRttController. A direct match to the IWifiChip.createRttController() method.
+ * Called on RTT controller lifecycle events. RTT controller is a singleton which will be
+ * created when possible (after first lifecycle registration) and destroyed if necessary.
*
- * Returns the created IWifiRttController or a null on error.
+ * Determination of availability is determined by the HAL. Creation attempts (if requested
+ * by registration of interface) will be done on any mode changes.
*/
- public IWifiRttController createRttController() {
- if (VDBG) Log.d(TAG, "createRttController");
- synchronized (mLock) {
- if (mWifi == null) {
- Log.e(TAG, "createRttController: null IWifi");
- return null;
- }
-
- WifiChipInfo[] chipInfos = getAllChipInfo();
- if (chipInfos == null) {
- Log.e(TAG, "createRttController: no chip info found");
- stopWifi(); // major error: shutting down
- return null;
- }
-
- for (WifiChipInfo chipInfo : chipInfos) {
- Mutable<IWifiRttController> rttResp = new Mutable<>();
- try {
- chipInfo.chip.createRttController(null,
- (WifiStatus status, IWifiRttController rtt) -> {
- if (status.code == WifiStatusCode.SUCCESS) {
- rttResp.value = rtt;
- } else {
- Log.e(TAG,
- "IWifiChip.createRttController failed: " + statusString(
- status));
- }
- });
- } catch (RemoteException e) {
- Log.e(TAG, "IWifiChip.createRttController exception: " + e);
- }
- if (rttResp.value != null) {
- return rttResp.value;
- }
- }
+ public interface InterfaceRttControllerLifecycleCallback {
+ /**
+ * Called when an RTT controller was created (or for newly registered listeners - if it
+ * was already available). The controller provided by this callback may be destroyed by
+ * the HAL at which point the {@link #onRttControllerDestroyed()} will be called.
+ *
+ * Note: this callback can be triggered to replace an existing controller (instead of
+ * calling the Destroyed callback in between).
+ *
+ * @param controller The RTT controller object.
+ */
+ void onNewRttController(@NonNull IWifiRttController controller);
- Log.e(TAG, "createRttController: not available from any of the chips");
- return null;
- }
+ /**
+ * Called when the previously provided RTT controller is destroyed. Clients must discard
+ * their copy. A new copy may be provided later by
+ * {@link #onNewRttController(IWifiRttController)}.
+ */
+ void onRttControllerDestroyed();
}
// internal state
@@ -496,8 +521,11 @@ public class HalDeviceManager {
private IServiceManager mServiceManager;
private IWifi mWifi;
+ private IWifiRttController mIWifiRttController;
private final WifiEventCallback mWifiEventCallback = new WifiEventCallback();
private final Set<ManagerStatusListenerProxy> mManagerStatusListeners = new HashSet<>();
+ private final Set<InterfaceRttControllerLifecycleCallbackProxy>
+ mRttControllerLifecycleCallbacks = new HashSet<>();
private final SparseArray<Map<InterfaceAvailableForRequestListenerProxy, Boolean>>
mInterfaceAvailableForRequestListeners = new SparseArray<>();
private final SparseArray<IWifiChipEventCallback.Stub> mDebugCallbacks = new SparseArray<>();
@@ -594,6 +622,10 @@ public class HalDeviceManager {
mInterfaceAvailableForRequestListeners.get(IfaceType.AP).clear();
mInterfaceAvailableForRequestListeners.get(IfaceType.P2P).clear();
mInterfaceAvailableForRequestListeners.get(IfaceType.NAN).clear();
+
+ mIWifiRttController = null;
+ dispatchRttControllerLifecycleOnDestroyed();
+ mRttControllerLifecycleCallbacks.clear();
}
private final HwRemoteBinder.DeathRecipient mServiceManagerDeathRecipient =
@@ -1787,6 +1819,7 @@ public class HalDeviceManager {
WifiStatus status = ifaceCreationData.chipInfo.chip.configureChip(
ifaceCreationData.chipModeId);
+ updateRttControllerOnModeChange();
if (status.code != WifiStatusCode.SUCCESS) {
Log.e(TAG, "executeChipReconfiguration: configureChip error: "
+ statusString(status));
@@ -2077,6 +2110,135 @@ public class HalDeviceManager {
}
}
+ private class InterfaceRttControllerLifecycleCallbackProxy implements
+ InterfaceRttControllerLifecycleCallback {
+ private InterfaceRttControllerLifecycleCallback mCallback;
+ private Handler mHandler;
+
+ InterfaceRttControllerLifecycleCallbackProxy(
+ InterfaceRttControllerLifecycleCallback callback, Handler handler) {
+ mCallback = callback;
+ mHandler = handler;
+ }
+
+ // override equals & hash to make sure that the container HashSet is unique with respect to
+ // the contained listener
+ @Override
+ public boolean equals(Object obj) {
+ return mCallback == ((InterfaceRttControllerLifecycleCallbackProxy) obj).mCallback;
+ }
+
+ @Override
+ public int hashCode() {
+ return mCallback.hashCode();
+ }
+
+ @Override
+ public void onNewRttController(IWifiRttController controller) {
+ mHandler.post(() -> mCallback.onNewRttController(controller));
+ }
+
+ @Override
+ public void onRttControllerDestroyed() {
+ mHandler.post(() -> mCallback.onRttControllerDestroyed());
+ }
+ }
+
+ private void dispatchRttControllerLifecycleOnNew() {
+ if (VDBG) {
+ Log.v(TAG, "dispatchRttControllerLifecycleOnNew: # cbs="
+ + mRttControllerLifecycleCallbacks.size());
+ }
+ for (InterfaceRttControllerLifecycleCallbackProxy cbp : mRttControllerLifecycleCallbacks) {
+ cbp.onNewRttController(mIWifiRttController);
+ }
+ }
+
+ private void dispatchRttControllerLifecycleOnDestroyed() {
+ for (InterfaceRttControllerLifecycleCallbackProxy cbp : mRttControllerLifecycleCallbacks) {
+ cbp.onRttControllerDestroyed();
+ }
+ }
+
+
+ /**
+ * Updates the RttController when the chip mode is changed:
+ * - Handles callbacks to registered listeners
+ * - Handles creation of new RttController
+ */
+ private void updateRttControllerOnModeChange() {
+ synchronized (mLock) {
+ boolean controllerDestroyed = mIWifiRttController != null;
+ mIWifiRttController = null;
+ if (mRttControllerLifecycleCallbacks.size() == 0) {
+ Log.d(TAG, "updateRttController: no one is interested in RTT controllers");
+ return;
+ }
+
+ IWifiRttController newRttController = createRttControllerIfPossible();
+ if (newRttController == null) {
+ if (controllerDestroyed) {
+ dispatchRttControllerLifecycleOnDestroyed();
+ }
+ } else {
+ mIWifiRttController = newRttController;
+ dispatchRttControllerLifecycleOnNew();
+ }
+ }
+ }
+
+ /**
+ * Try to create a new RttController.
+ *
+ * @return The new RttController - or null on failure.
+ */
+ private IWifiRttController createRttControllerIfPossible() {
+ synchronized (mLock) {
+ if (!isWifiStarted()) {
+ Log.d(TAG, "createRttControllerIfPossible: Wifi is not started");
+ return null;
+ }
+
+ WifiChipInfo[] chipInfos = getAllChipInfo();
+ if (chipInfos == null) {
+ Log.d(TAG, "createRttControllerIfPossible: no chip info found - most likely chip "
+ + "not up yet");
+ return null;
+ }
+
+ for (WifiChipInfo chipInfo : chipInfos) {
+ if (!chipInfo.currentModeIdValid) {
+ if (VDBG) {
+ Log.d(TAG, "createRttControllerIfPossible: chip not configured yet: "
+ + chipInfo);
+ }
+ continue;
+ }
+
+ Mutable<IWifiRttController> rttResp = new Mutable<>();
+ try {
+ chipInfo.chip.createRttController(null,
+ (WifiStatus status, IWifiRttController rtt) -> {
+ if (status.code == WifiStatusCode.SUCCESS) {
+ rttResp.value = rtt;
+ } else {
+ Log.e(TAG, "IWifiChip.createRttController failed: "
+ + statusString(status));
+ }
+ });
+ } catch (RemoteException e) {
+ Log.e(TAG, "IWifiChip.createRttController exception: " + e);
+ }
+ if (rttResp.value != null) {
+ return rttResp.value;
+ }
+ }
+ }
+
+ Log.w(TAG, "createRttControllerIfPossible: not available from any of the chips");
+ return null;
+ }
+
// general utilities
private static String statusString(WifiStatus status) {
diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java
index 7351b720a..29b38aed7 100644
--- a/service/java/com/android/server/wifi/WifiNative.java
+++ b/service/java/com/android/server/wifi/WifiNative.java
@@ -18,13 +18,10 @@ package com.android.server.wifi;
import android.annotation.IntDef;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.net.InterfaceConfiguration;
import android.net.MacAddress;
import android.net.TrafficStats;
import android.net.apf.ApfCapabilities;
-import android.net.wifi.RttManager;
-import android.net.wifi.RttManager.ResponderConfig;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiScanner;
@@ -2303,51 +2300,6 @@ public class WifiNative {
return mWifiVendorHal.getSupportedFeatureSet(ifaceName);
}
- public static interface RttEventHandler {
- void onRttResults(RttManager.RttResult[] result);
- }
-
- /**
- * Starts a new rtt request
- *
- * @param params RTT request params. Refer to {@link RttManager#RttParams}.
- * @param handler Callback to be invoked to notify any results.
- * @return true if the request was successful, false otherwise.
- */
- public boolean requestRtt(
- RttManager.RttParams[] params, RttEventHandler handler) {
- return mWifiVendorHal.requestRtt(params, handler);
- }
-
- /**
- * Cancels an outstanding rtt request
- *
- * @param params RTT request params. Refer to {@link RttManager#RttParams}
- * @return true if there was an outstanding request and it was successfully cancelled
- */
- public boolean cancelRtt(RttManager.RttParams[] params) {
- return mWifiVendorHal.cancelRtt(params);
- }
-
- /**
- * Enable RTT responder role on the device. Returns {@link ResponderConfig} if the responder
- * role is successfully enabled, {@code null} otherwise.
- *
- * @param timeoutSeconds timeout to use for the responder.
- */
- @Nullable
- public ResponderConfig enableRttResponder(int timeoutSeconds) {
- return mWifiVendorHal.enableRttResponder(timeoutSeconds);
- }
-
- /**
- * Disable RTT responder role. Returns {@code true} if responder role is successfully disabled,
- * {@code false} otherwise.
- */
- public boolean disableRttResponder() {
- return mWifiVendorHal.disableRttResponder();
- }
-
/**
* Set the MAC OUI during scanning.
* An OUI {Organizationally Unique Identifier} is a 24-bit number that
@@ -2362,13 +2314,6 @@ public class WifiNative {
}
/**
- * RTT (Round Trip Time) measurement capabilities of the device.
- */
- public RttManager.RttCapabilities getRttCapabilities() {
- return mWifiVendorHal.getRttCapabilities();
- }
-
- /**
* Get the APF (Android Packet Filter) capabilities of the device
* @param ifaceName Name of the interface.
*/
diff --git a/service/java/com/android/server/wifi/WifiVendorHal.java b/service/java/com/android/server/wifi/WifiVendorHal.java
index 5666dd386..77da7667f 100644
--- a/service/java/com/android/server/wifi/WifiVendorHal.java
+++ b/service/java/com/android/server/wifi/WifiVendorHal.java
@@ -20,18 +20,9 @@ import android.hardware.wifi.V1_0.IWifiApIface;
import android.hardware.wifi.V1_0.IWifiChip;
import android.hardware.wifi.V1_0.IWifiChipEventCallback;
import android.hardware.wifi.V1_0.IWifiIface;
-import android.hardware.wifi.V1_0.IWifiRttController;
-import android.hardware.wifi.V1_0.IWifiRttControllerEventCallback;
import android.hardware.wifi.V1_0.IWifiStaIface;
import android.hardware.wifi.V1_0.IWifiStaIfaceEventCallback;
import android.hardware.wifi.V1_0.IfaceType;
-import android.hardware.wifi.V1_0.RttBw;
-import android.hardware.wifi.V1_0.RttConfig;
-import android.hardware.wifi.V1_0.RttPeerType;
-import android.hardware.wifi.V1_0.RttPreamble;
-import android.hardware.wifi.V1_0.RttResponder;
-import android.hardware.wifi.V1_0.RttResult;
-import android.hardware.wifi.V1_0.RttType;
import android.hardware.wifi.V1_0.StaBackgroundScanBucketEventReportSchemeMask;
import android.hardware.wifi.V1_0.StaBackgroundScanBucketParameters;
import android.hardware.wifi.V1_0.StaBackgroundScanParameters;
@@ -44,7 +35,6 @@ import android.hardware.wifi.V1_0.StaScanData;
import android.hardware.wifi.V1_0.StaScanDataFlagMask;
import android.hardware.wifi.V1_0.StaScanResult;
import android.hardware.wifi.V1_0.WifiBand;
-import android.hardware.wifi.V1_0.WifiChannelWidthInMhz;
import android.hardware.wifi.V1_0.WifiDebugHostWakeReasonStats;
import android.hardware.wifi.V1_0.WifiDebugPacketFateFrameType;
import android.hardware.wifi.V1_0.WifiDebugRingBufferFlags;
@@ -58,8 +48,6 @@ import android.hardware.wifi.V1_0.WifiStatus;
import android.hardware.wifi.V1_0.WifiStatusCode;
import android.net.MacAddress;
import android.net.apf.ApfCapabilities;
-import android.net.wifi.RttManager;
-import android.net.wifi.RttManager.ResponderConfig;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
@@ -247,7 +235,6 @@ public class WifiVendorHal {
// Vendor HAL HIDL interface objects.
private IWifiChip mIWifiChip;
- private IWifiRttController mIWifiRttController;
private HashMap<String, IWifiStaIface> mIWifiStaIfaces = new HashMap<>();
private HashMap<String, IWifiApIface> mIWifiApIfaces = new HashMap<>();
private final HalDeviceManager mHalDeviceManager;
@@ -255,7 +242,6 @@ public class WifiVendorHal {
private final IWifiStaIfaceEventCallback mIWifiStaIfaceEventCallback;
private final ChipEventCallback mIWifiChipEventCallback;
private final ChipEventCallbackV12 mIWifiChipEventCallbackV12;
- private final RttEventCallback mRttEventCallback;
// Plumbing for event handling.
//
@@ -274,7 +260,6 @@ public class WifiVendorHal {
mIWifiStaIfaceEventCallback = new StaIfaceEventCallback();
mIWifiChipEventCallback = new ChipEventCallback();
mIWifiChipEventCallbackV12 = new ChipEventCallbackV12();
- mRttEventCallback = new RttEventCallback();
}
public static final Object sLock = new Object();
@@ -427,15 +412,6 @@ public class WifiVendorHal {
mLog.err("Failed to register STA iface callback").flush();
return stringResult(null);
}
- mIWifiRttController = mHalDeviceManager.createRttController();
- if (mIWifiRttController == null) {
- mLog.err("Failed to create RTT controller").flush();
- return stringResult(null);
- }
- if (!registerRttEventCallback()) {
- mLog.err("Failed to register RTT controller callback").flush();
- return stringResult(null);
- }
if (!retrieveWifiChip((IWifiIface) iface)) {
mLog.err("Failed to get wifi chip").flush();
return stringResult(null);
@@ -601,23 +577,6 @@ public class WifiVendorHal {
}
/**
- * Registers RTT event callback. Returns whether the registration is successful.
- */
- private boolean registerRttEventCallback() {
- synchronized (sLock) {
- if (mIWifiRttController == null) return boolResult(false);
- if (mRttEventCallback == null) return boolResult(false);
- try {
- WifiStatus status = mIWifiRttController.registerEventCallback(mRttEventCallback);
- return ok(status);
- } catch (RemoteException e) {
- handleRemoteException(e);
- return false;
- }
- }
- }
-
- /**
* Stops the HAL
*/
public void stopVendorHal() {
@@ -637,7 +596,6 @@ public class WifiVendorHal {
mIWifiChip = null;
mIWifiStaIfaces.clear();
mIWifiApIfaces.clear();
- mIWifiRttController = null;
mDriverDescription = null;
mFirmwareDescription = null;
}
@@ -1247,510 +1205,6 @@ public class WifiVendorHal {
return featureSet;
}
- /* RTT related commands/events */
-
- /**
- * RTT (Round Trip Time) measurement capabilities of the device.
- */
- public RttManager.RttCapabilities getRttCapabilities() {
- class AnswerBox {
- public RttManager.RttCapabilities value = null;
- }
- synchronized (sLock) {
- if (mIWifiRttController == null) return null;
- try {
- AnswerBox box = new AnswerBox();
- mIWifiRttController.getCapabilities((status, capabilities) -> {
- if (!ok(status)) return;
- mVerboseLog.info("rtt capabilites %").c(capabilities.toString()).flush();
- RttManager.RttCapabilities ans = new RttManager.RttCapabilities();
- ans.oneSidedRttSupported = capabilities.rttOneSidedSupported;
- ans.twoSided11McRttSupported = capabilities.rttFtmSupported;
- ans.lciSupported = capabilities.lciSupported;
- ans.lcrSupported = capabilities.lcrSupported;
- ans.preambleSupported = frameworkPreambleFromHalPreamble(
- capabilities.preambleSupport);
- ans.bwSupported = frameworkBwFromHalBw(capabilities.bwSupport);
- ans.responderSupported = capabilities.responderSupported;
- ans.secureRttSupported = false;
- ans.mcVersion = ((int) capabilities.mcVersion) & 0xff;
- box.value = ans;
- });
- return box.value;
- } catch (RemoteException e) {
- handleRemoteException(e);
- return null;
- }
- }
- }
-
- private int mRttCmdIdNext = 1; // used to generate new command ids
- private int mRttCmdId; // id of currently active request
- // Event handler for current active RTT request.
- private WifiNative.RttEventHandler mRttEventHandler;
-
- /**
- * Receives a callback from the Hal and passes it along to our client using RttEventHandler
- */
- private class RttEventCallback extends IWifiRttControllerEventCallback.Stub {
-
- @Override
- public void onResults(int cmdId, java.util.ArrayList<RttResult> results) {
- WifiNative.RttEventHandler eventHandler;
- synchronized (sLock) {
- if (cmdId != mRttCmdId || mRttEventHandler == null) return;
- eventHandler = mRttEventHandler;
- // Reset the command id for RTT operations in WifiVendorHal.
- WifiVendorHal.this.mRttCmdId = 0;
- }
- RttManager.RttResult[] rtt = new RttManager.RttResult[results.size()];
- for (int i = 0; i < rtt.length; i++) {
- rtt[i] = frameworkRttResultFromHalRttResult(results.get(i));
- }
- eventHandler.onRttResults(rtt);
- }
- }
-
- /**
- * Converts a Hal RttResult to a RttManager.RttResult
- */
- @VisibleForTesting
- static RttManager.RttResult frameworkRttResultFromHalRttResult(RttResult result) {
- RttManager.RttResult ans = new RttManager.RttResult();
- ans.bssid = NativeUtil.macAddressFromByteArray(result.addr);
- ans.burstNumber = result.burstNum;
- ans.measurementFrameNumber = result.measurementNumber;
- ans.successMeasurementFrameNumber = result.successNumber;
- ans.frameNumberPerBurstPeer = result.numberPerBurstPeer;
- ans.status = result.status; //TODO(b/35138520) - don't assume identity translation
- ans.retryAfterDuration = result.retryAfterDuration;
- ans.measurementType = result.type;
- ans.rssi = result.rssi;
- ans.rssiSpread = result.rssiSpread;
- //TODO(b/35138520) Fix HAL and framework to use the same units
- ans.txRate = result.txRate.bitRateInKbps;
- ans.rxRate = result.rxRate.bitRateInKbps;
- ans.rtt = result.rtt;
- ans.rttStandardDeviation = result.rttSd;
- ans.rttSpread = result.rttSpread;
- //TODO(b/35138520) These divide-by-10s were in the legacy Hal
- ans.distance = result.distanceInMm / 10; // Convert cm to mm
- ans.distanceStandardDeviation = result.distanceSdInMm / 10; // Convert cm to mm
- ans.distanceSpread = result.distanceSpreadInMm / 10;
-
- ans.ts = result.timeStampInUs;
- ans.burstDuration = result.burstDurationInMs;
- ans.negotiatedBurstNum = result.negotiatedBurstNum;
- ans.LCI = ieFromHal(result.lci);
- ans.LCR = ieFromHal(result.lcr);
- ans.secure = false; // Not present in HIDL HAL
- return ans;
- }
-
- /**
- * Convert a Hal WifiInformationElement to its RttManager equivalent
- */
- @VisibleForTesting
- static RttManager.WifiInformationElement ieFromHal(
- android.hardware.wifi.V1_0.WifiInformationElement ie) {
- if (ie == null) return null;
- RttManager.WifiInformationElement ans = new RttManager.WifiInformationElement();
- ans.id = ie.id;
- ans.data = NativeUtil.byteArrayFromArrayList(ie.data);
- return ans;
- }
-
- @VisibleForTesting
- static RttConfig halRttConfigFromFrameworkRttParams(RttManager.RttParams params) {
- RttConfig rttConfig = new RttConfig();
- if (params.bssid != null) {
- byte[] addr = NativeUtil.macAddressToByteArray(params.bssid);
- for (int i = 0; i < rttConfig.addr.length; i++) {
- rttConfig.addr[i] = addr[i];
- }
- }
- rttConfig.type = halRttTypeFromFrameworkRttType(params.requestType);
- rttConfig.peer = halPeerFromFrameworkPeer(params.deviceType);
- rttConfig.channel.width = halChannelWidthFromFrameworkChannelWidth(params.channelWidth);
- rttConfig.channel.centerFreq = params.frequency;
- rttConfig.channel.centerFreq0 = params.centerFreq0;
- rttConfig.channel.centerFreq1 = params.centerFreq1;
- rttConfig.burstPeriod = params.interval; // In 100ms units, 0 means no specific
- rttConfig.numBurst = params.numberBurst;
- rttConfig.numFramesPerBurst = params.numSamplesPerBurst;
- rttConfig.numRetriesPerRttFrame = params.numRetriesPerMeasurementFrame;
- rttConfig.numRetriesPerFtmr = params.numRetriesPerFTMR;
- rttConfig.mustRequestLci = params.LCIRequest;
- rttConfig.mustRequestLcr = params.LCRRequest;
- rttConfig.burstDuration = params.burstTimeout;
- rttConfig.preamble = halPreambleFromFrameworkPreamble(params.preamble);
- rttConfig.bw = halBwFromFrameworkBw(params.bandwidth);
- return rttConfig;
- }
-
- @VisibleForTesting
- static int halRttTypeFromFrameworkRttType(int frameworkRttType) {
- switch (frameworkRttType) {
- case RttManager.RTT_TYPE_ONE_SIDED:
- return RttType.ONE_SIDED;
- case RttManager.RTT_TYPE_TWO_SIDED:
- return RttType.TWO_SIDED;
- default:
- throw new IllegalArgumentException("bad " + frameworkRttType);
- }
- }
-
- @VisibleForTesting
- static int frameworkRttTypeFromHalRttType(int halType) {
- switch (halType) {
- case RttType.ONE_SIDED:
- return RttManager.RTT_TYPE_ONE_SIDED;
- case RttType.TWO_SIDED:
- return RttManager.RTT_TYPE_TWO_SIDED;
- default:
- throw new IllegalArgumentException("bad " + halType);
- }
- }
-
- @VisibleForTesting
- static int halPeerFromFrameworkPeer(int frameworkPeer) {
- switch (frameworkPeer) {
- case RttManager.RTT_PEER_TYPE_AP:
- return RttPeerType.AP;
- case RttManager.RTT_PEER_TYPE_STA:
- return RttPeerType.STA;
- case RttManager.RTT_PEER_P2P_GO:
- return RttPeerType.P2P_GO;
- case RttManager.RTT_PEER_P2P_CLIENT:
- return RttPeerType.P2P_CLIENT;
- case RttManager.RTT_PEER_NAN:
- return RttPeerType.NAN;
- default:
- throw new IllegalArgumentException("bad " + frameworkPeer);
- }
- }
-
- @VisibleForTesting
- static int frameworkPeerFromHalPeer(int halPeer) {
- switch (halPeer) {
- case RttPeerType.AP:
- return RttManager.RTT_PEER_TYPE_AP;
- case RttPeerType.STA:
- return RttManager.RTT_PEER_TYPE_STA;
- case RttPeerType.P2P_GO:
- return RttManager.RTT_PEER_P2P_GO;
- case RttPeerType.P2P_CLIENT:
- return RttManager.RTT_PEER_P2P_CLIENT;
- case RttPeerType.NAN:
- return RttManager.RTT_PEER_NAN;
- default:
- throw new IllegalArgumentException("bad " + halPeer);
-
- }
- }
-
- @VisibleForTesting
- static int halChannelWidthFromFrameworkChannelWidth(int frameworkChannelWidth) {
- switch (frameworkChannelWidth) {
- case ScanResult.CHANNEL_WIDTH_20MHZ:
- return WifiChannelWidthInMhz.WIDTH_20;
- case ScanResult.CHANNEL_WIDTH_40MHZ:
- return WifiChannelWidthInMhz.WIDTH_40;
- case ScanResult.CHANNEL_WIDTH_80MHZ:
- return WifiChannelWidthInMhz.WIDTH_80;
- case ScanResult.CHANNEL_WIDTH_160MHZ:
- return WifiChannelWidthInMhz.WIDTH_160;
- case ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ:
- return WifiChannelWidthInMhz.WIDTH_80P80;
- default:
- throw new IllegalArgumentException("bad " + frameworkChannelWidth);
- }
- }
-
- @VisibleForTesting
- static int frameworkChannelWidthFromHalChannelWidth(int halChannelWidth) {
- switch (halChannelWidth) {
- case WifiChannelWidthInMhz.WIDTH_20:
- return ScanResult.CHANNEL_WIDTH_20MHZ;
- case WifiChannelWidthInMhz.WIDTH_40:
- return ScanResult.CHANNEL_WIDTH_40MHZ;
- case WifiChannelWidthInMhz.WIDTH_80:
- return ScanResult.CHANNEL_WIDTH_80MHZ;
- case WifiChannelWidthInMhz.WIDTH_160:
- return ScanResult.CHANNEL_WIDTH_160MHZ;
- case WifiChannelWidthInMhz.WIDTH_80P80:
- return ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ;
- default:
- throw new IllegalArgumentException("bad " + halChannelWidth);
- }
- }
-
- @VisibleForTesting
- static int halPreambleFromFrameworkPreamble(int rttManagerPreamble) {
- BitMask checkoff = new BitMask(rttManagerPreamble);
- int flags = 0;
- if (checkoff.testAndClear(RttManager.PREAMBLE_LEGACY)) {
- flags |= RttPreamble.LEGACY;
- }
- if (checkoff.testAndClear(RttManager.PREAMBLE_HT)) {
- flags |= RttPreamble.HT;
- }
- if (checkoff.testAndClear(RttManager.PREAMBLE_VHT)) {
- flags |= RttPreamble.VHT;
- }
- if (checkoff.value != 0) {
- throw new IllegalArgumentException("bad " + rttManagerPreamble);
- }
- return flags;
- }
-
- @VisibleForTesting
- static int frameworkPreambleFromHalPreamble(int halPreamble) {
- BitMask checkoff = new BitMask(halPreamble);
- int flags = 0;
- if (checkoff.testAndClear(RttPreamble.LEGACY)) {
- flags |= RttManager.PREAMBLE_LEGACY;
- }
- if (checkoff.testAndClear(RttPreamble.HT)) {
- flags |= RttManager.PREAMBLE_HT;
- }
- if (checkoff.testAndClear(RttPreamble.VHT)) {
- flags |= RttManager.PREAMBLE_VHT;
- }
- if (checkoff.value != 0) {
- throw new IllegalArgumentException("bad " + halPreamble);
- }
- return flags;
- }
-
- @VisibleForTesting
- static int halBwFromFrameworkBw(int rttManagerBandwidth) {
- BitMask checkoff = new BitMask(rttManagerBandwidth);
- int flags = 0;
- if (checkoff.testAndClear(RttManager.RTT_BW_5_SUPPORT)) {
- flags |= RttBw.BW_5MHZ;
- }
- if (checkoff.testAndClear(RttManager.RTT_BW_10_SUPPORT)) {
- flags |= RttBw.BW_10MHZ;
- }
- if (checkoff.testAndClear(RttManager.RTT_BW_20_SUPPORT)) {
- flags |= RttBw.BW_20MHZ;
- }
- if (checkoff.testAndClear(RttManager.RTT_BW_40_SUPPORT)) {
- flags |= RttBw.BW_40MHZ;
- }
- if (checkoff.testAndClear(RttManager.RTT_BW_80_SUPPORT)) {
- flags |= RttBw.BW_80MHZ;
- }
- if (checkoff.testAndClear(RttManager.RTT_BW_160_SUPPORT)) {
- flags |= RttBw.BW_160MHZ;
- }
- if (checkoff.value != 0) {
- throw new IllegalArgumentException("bad " + rttManagerBandwidth);
- }
- return flags;
- }
-
- @VisibleForTesting
- static int frameworkBwFromHalBw(int rttBw) {
- BitMask checkoff = new BitMask(rttBw);
- int flags = 0;
- if (checkoff.testAndClear(RttBw.BW_5MHZ)) {
- flags |= RttManager.RTT_BW_5_SUPPORT;
- }
- if (checkoff.testAndClear(RttBw.BW_10MHZ)) {
- flags |= RttManager.RTT_BW_10_SUPPORT;
- }
- if (checkoff.testAndClear(RttBw.BW_20MHZ)) {
- flags |= RttManager.RTT_BW_20_SUPPORT;
- }
- if (checkoff.testAndClear(RttBw.BW_40MHZ)) {
- flags |= RttManager.RTT_BW_40_SUPPORT;
- }
- if (checkoff.testAndClear(RttBw.BW_80MHZ)) {
- flags |= RttManager.RTT_BW_80_SUPPORT;
- }
- if (checkoff.testAndClear(RttBw.BW_160MHZ)) {
- flags |= RttManager.RTT_BW_160_SUPPORT;
- }
- if (checkoff.value != 0) {
- throw new IllegalArgumentException("bad " + rttBw);
- }
- return flags;
- }
-
- @VisibleForTesting
- static ArrayList<RttConfig> halRttConfigArrayFromFrameworkRttParamsArray(
- RttManager.RttParams[] params) {
- final int length = params.length;
- ArrayList<RttConfig> configs = new ArrayList<RttConfig>(length);
- for (int i = 0; i < length; i++) {
- RttConfig config = halRttConfigFromFrameworkRttParams(params[i]);
- if (config != null) {
- configs.add(config);
- }
- }
- return configs;
- }
-
- /**
- * Starts a new rtt request
- *
- * @param params
- * @param handler
- * @return success indication
- */
- public boolean requestRtt(RttManager.RttParams[] params, WifiNative.RttEventHandler handler) {
- ArrayList<RttConfig> rttConfigs;
- try {
- rttConfigs = halRttConfigArrayFromFrameworkRttParamsArray(params);
- } catch (IllegalArgumentException e) {
- mLog.err("Illegal argument for RTT request").c(e.toString()).flush();
- return false;
- }
- synchronized (sLock) {
- if (mIWifiRttController == null) return boolResult(false);
- if (mRttCmdId != 0) return boolResult(false);
- mRttCmdId = mRttCmdIdNext++;
- mRttEventHandler = handler;
- if (mRttCmdIdNext <= 0) mRttCmdIdNext = 1;
- try {
- WifiStatus status = mIWifiRttController.rangeRequest(mRttCmdId, rttConfigs);
- if (ok(status)) return true;
- mRttCmdId = 0;
- return false;
- } catch (RemoteException e) {
- handleRemoteException(e);
- return false;
- }
- }
- }
-
- /**
- * Cancels an outstanding rtt request
- *
- * @param params
- * @return true if there was an outstanding request and it was successfully cancelled
- */
- public boolean cancelRtt(RttManager.RttParams[] params) {
- ArrayList<RttConfig> rttConfigs = halRttConfigArrayFromFrameworkRttParamsArray(params);
- synchronized (sLock) {
- if (mIWifiRttController == null) return boolResult(false);
- if (mRttCmdId == 0) return boolResult(false);
- ArrayList<byte[/* 6 */]> addrs = new ArrayList<byte[]>(rttConfigs.size());
- for (RttConfig x : rttConfigs) addrs.add(x.addr);
- try {
- WifiStatus status = mIWifiRttController.rangeCancel(mRttCmdId, addrs);
- mRttCmdId = 0;
- if (!ok(status)) return false;
- return true;
- } catch (RemoteException e) {
- handleRemoteException(e);
- return false;
- }
- }
- }
-
- private int mRttResponderCmdId = 0;
-
- /**
- * Get RTT responder information e.g. WiFi channel to enable responder on.
- *
- * @return info Instance of |RttResponder|, or null for error.
- */
- private RttResponder getRttResponder() {
- class AnswerBox {
- public RttResponder value = null;
- }
- synchronized (sLock) {
- if (mIWifiRttController == null) return null;
- AnswerBox answer = new AnswerBox();
- try {
- mIWifiRttController.getResponderInfo((status, info) -> {
- if (!ok(status)) return;
- answer.value = info;
- });
- return answer.value;
- } catch (RemoteException e) {
- handleRemoteException(e);
- return null;
- }
- }
- }
-
- /**
- * Convert Hal RttResponder to a framework ResponderConfig
- *
- * @param info Instance of |RttResponder|
- * @return framework version of same
- */
- private ResponderConfig frameworkResponderConfigFromHalRttResponder(RttResponder info) {
- ResponderConfig config = new ResponderConfig();
- config.frequency = info.channel.centerFreq;
- config.centerFreq0 = info.channel.centerFreq0;
- config.centerFreq1 = info.channel.centerFreq1;
- config.channelWidth = frameworkChannelWidthFromHalChannelWidth(info.channel.width);
- config.preamble = frameworkPreambleFromHalPreamble(info.preamble);
- return config;
- }
-
- /**
- * Enables RTT responder role on the device.
- *
- * @return {@link ResponderConfig} if the responder role is successfully enabled,
- * {@code null} otherwise.
- */
- public ResponderConfig enableRttResponder(int timeoutSeconds) {
- RttResponder info = getRttResponder();
- synchronized (sLock) {
- if (mIWifiRttController == null) return null;
- if (mRttResponderCmdId != 0) {
- mLog.err("responder mode already enabled - this shouldn't happen").flush();
- return null;
- }
- ResponderConfig config = null;
- int id = mRttCmdIdNext++;
- if (mRttCmdIdNext <= 0) mRttCmdIdNext = 1;
- try {
- WifiStatus status = mIWifiRttController.enableResponder(
- /* cmdId */id,
- /* WifiChannelInfo channelHint */null,
- timeoutSeconds, info);
- if (ok(status)) {
- mRttResponderCmdId = id;
- config = frameworkResponderConfigFromHalRttResponder(info);
- mVerboseLog.i("enabling rtt " + mRttResponderCmdId);
- }
- return config;
- } catch (RemoteException e) {
- handleRemoteException(e);
- return null;
- }
- }
- }
-
- /**
- * Disables RTT responder role.
- *
- * @return {@code true} if responder role is successfully disabled,
- * {@code false} otherwise.
- */
- public boolean disableRttResponder() {
- synchronized (sLock) {
- if (mIWifiRttController == null) return boolResult(false);
- if (mRttResponderCmdId == 0) return boolResult(false);
- try {
- WifiStatus status = mIWifiRttController.disableResponder(mRttResponderCmdId);
- mRttResponderCmdId = 0;
- if (!ok(status)) return false;
- return true;
- } catch (RemoteException e) {
- handleRemoteException(e);
- return false;
- }
- }
- }
-
/**
* Set the MAC OUI during scanning.
* <p>
diff --git a/service/java/com/android/server/wifi/rtt/RttNative.java b/service/java/com/android/server/wifi/rtt/RttNative.java
index accd1a2f8..29b0a139f 100644
--- a/service/java/com/android/server/wifi/rtt/RttNative.java
+++ b/service/java/com/android/server/wifi/rtt/RttNative.java
@@ -57,6 +57,40 @@ public class RttNative extends IWifiRttControllerEventCallback.Stub {
private volatile IWifiRttController mIWifiRttController;
private volatile RttCapabilities mRttCapabilities;
+ private final HalDeviceManager.InterfaceRttControllerLifecycleCallback mRttLifecycleCb =
+ new HalDeviceManager.InterfaceRttControllerLifecycleCallback() {
+ @Override
+ public void onNewRttController(IWifiRttController controller) {
+ if (mDbg) Log.d(TAG, "onNewRttController: controller=" + controller);
+ synchronized (mLock) {
+ try {
+ controller.registerEventCallback(RttNative.this);
+ } catch (RemoteException e) {
+ Log.e(TAG, "onNewRttController: exception registering callback: " + e);
+ if (mIWifiRttController != null) {
+ mIWifiRttController = null;
+ mRttService.disable();
+ }
+ return;
+ }
+
+ mIWifiRttController = controller;
+ mRttService.enableIfPossible();
+ updateRttCapabilities();
+ }
+ }
+
+ @Override
+ public void onRttControllerDestroyed() {
+ if (mDbg) Log.d(TAG, "onRttControllerDestroyed");
+ synchronized (mLock) {
+ mIWifiRttController = null;
+ mRttCapabilities = null;
+ mRttService.disable();
+ }
+ }
+ };
+
public RttNative(RttServiceImpl rttService, HalDeviceManager halDeviceManager) {
mRttService = rttService;
mHalDeviceManager = halDeviceManager;
@@ -70,9 +104,14 @@ public class RttNative extends IWifiRttControllerEventCallback.Stub {
mHalDeviceManager.initialize();
mHalDeviceManager.registerStatusListener(() -> {
if (VDBG) Log.d(TAG, "hdm.onStatusChanged");
- updateController();
+ if (mHalDeviceManager.isStarted()) {
+ mHalDeviceManager.registerRttControllerLifecycleCallback(mRttLifecycleCb,
+ handler);
+ }
}, handler);
- updateController();
+ if (mHalDeviceManager.isStarted()) {
+ mHalDeviceManager.registerRttControllerLifecycleCallback(mRttLifecycleCb, handler);
+ }
}
}
@@ -83,67 +122,36 @@ public class RttNative extends IWifiRttControllerEventCallback.Stub {
return mIWifiRttController != null;
}
- private void updateController() {
- if (mDbg) Log.v(TAG, "updateController: mIWifiRttController=" + mIWifiRttController);
-
- // only care about isStarted (Wi-Fi started) not isReady - since if not
- // ready then Wi-Fi will also be down.
- synchronized (mLock) {
- IWifiRttController localWifiRttController = mIWifiRttController;
- if (mHalDeviceManager.isStarted()) {
- if (localWifiRttController == null) {
- localWifiRttController = mHalDeviceManager.createRttController();
- if (localWifiRttController == null) {
- Log.e(TAG, "updateController: Failed creating RTT controller - but Wifi is "
- + "started!");
- } else {
- try {
- localWifiRttController.registerEventCallback(this);
- } catch (RemoteException e) {
- Log.e(TAG, "updateController: exception registering callback: " + e);
- localWifiRttController = null;
- }
- }
- }
- } else {
- localWifiRttController = null;
- }
- mIWifiRttController = localWifiRttController;
-
- if (mIWifiRttController == null) {
- mRttService.disable();
- } else {
- mRttService.enableIfPossible();
- updateRttCapabilities();
- }
- }
- }
-
/**
* Updates the RTT capabilities.
*/
void updateRttCapabilities() {
+ if (mIWifiRttController == null) {
+ Log.e(TAG, "updateRttCapabilities: but a RTT controll is NULL!?");
+ return;
+ }
if (mRttCapabilities != null) {
return;
}
+ if (mDbg) Log.v(TAG, "updateRttCapabilities");
synchronized (mLock) {
try {
mIWifiRttController.getCapabilities(
(status, capabilities) -> {
if (status.code != WifiStatusCode.SUCCESS) {
- Log.e(TAG,
- "updateController: error requesting capabilities -- code="
- + status.code);
+ Log.e(TAG, "updateRttCapabilities: error requesting capabilities "
+ + "-- code=" + status.code);
return;
}
if (mDbg) {
- Log.v(TAG, "updateController: RTT capabilities=" + capabilities);
+ Log.v(TAG, "updateRttCapabilities: RTT capabilities="
+ + capabilities);
}
mRttCapabilities = capabilities;
});
} catch (RemoteException e) {
- Log.e(TAG, "updateController: exception requesting capabilities: " + e);
+ Log.e(TAG, "updateRttCapabilities: exception requesting capabilities: " + e);
}
if (mRttCapabilities != null && !mRttCapabilities.rttFtmSupported) {
@@ -171,12 +179,12 @@ public class RttNative extends IWifiRttControllerEventCallback.Stub {
"rangeRequest: cmdId=" + cmdId + ", # of requests=" + request.mRttPeers.size());
}
if (VDBG) Log.v(TAG, "rangeRequest: request=" + request);
- updateRttCapabilities();
synchronized (mLock) {
if (!isReady()) {
Log.e(TAG, "rangeRequest: RttController is null");
return false;
}
+ updateRttCapabilities();
ArrayList<RttConfig> rttConfig = convertRangingRequestToRttConfigs(request,
isCalledFromPrivilegedContext, mRttCapabilities);