[NAN] Add support for NAN RTT.

Provide API for NAN RTT through WifiNanManager. While NAN RTT could be executed
directly through RttManager the peer information is hidden by WifiNanManager (no
MAC address is exposed). Using WifiNanManager keeps the information hidden.

Bug: 26564277
Change-Id: I8deeb3f9e360dc05f2ea175d115f287590d50322
(cherry picked from commit fb8021c837)
This commit is contained in:
Etan Cohen
2016-05-09 15:30:06 -07:00
committed by Mitchell Wills
parent 271c03738c
commit 447b032334
6 changed files with 243 additions and 6 deletions

View File

@@ -15,4 +15,7 @@
*/
package android.net.wifi;
parcelable RttManager.RttCapabilities;
parcelable RttManager.RttCapabilities;
parcelable RttManager.ParcelableRttResults;
parcelable RttManager.ParcelableRttParams;

View File

@@ -472,6 +472,34 @@ public class RttManager {
preamble = PREAMBLE_HT;
bandwidth = RTT_BW_20_SUPPORT;
}
/**
* {@hide}
*/
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("deviceType=" + deviceType);
sb.append(", requestType=" + requestType);
sb.append(", secure=" + secure);
sb.append(", bssid=" + bssid);
sb.append(", frequency=" + frequency);
sb.append(", channelWidth=" + channelWidth);
sb.append(", centerFreq0=" + centerFreq0);
sb.append(", centerFreq1=" + centerFreq1);
sb.append(", num_samples=" + num_samples);
sb.append(", num_retries=" + num_retries);
sb.append(", numberBurst=" + numberBurst);
sb.append(", interval=" + interval);
sb.append(", numSamplesPerBurst=" + numSamplesPerBurst);
sb.append(", numRetriesPerMeasurementFrame=" + numRetriesPerMeasurementFrame);
sb.append(", numRetriesPerFTMR=" + numRetriesPerFTMR);
sb.append(", LCIRequest=" + LCIRequest);
sb.append(", LCRRequest=" + LCRRequest);
sb.append(", burstTimeout=" + burstTimeout);
sb.append(", preamble=" + preamble);
sb.append(", bandwidth=" + bandwidth);
return sb.toString();
}
}
/** pseudo-private class used to parcel arguments */
@@ -727,6 +755,51 @@ public class RttManager {
mResults = results;
}
/**
* {@hide}
*/
public String toString() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < mResults.length; ++i) {
sb.append("[" + i + "]: ");
sb.append("bssid=" + mResults[i].bssid);
sb.append(", burstNumber=" + mResults[i].burstNumber);
sb.append(", measurementFrameNumber=" + mResults[i].measurementFrameNumber);
sb.append(", successMeasurementFrameNumber="
+ mResults[i].successMeasurementFrameNumber);
sb.append(", frameNumberPerBurstPeer=" + mResults[i].frameNumberPerBurstPeer);
sb.append(", status=" + mResults[i].status);
sb.append(", requestType=" + mResults[i].requestType);
sb.append(", measurementType=" + mResults[i].measurementType);
sb.append(", retryAfterDuration=" + mResults[i].retryAfterDuration);
sb.append(", ts=" + mResults[i].ts);
sb.append(", rssi=" + mResults[i].rssi);
sb.append(", rssi_spread=" + mResults[i].rssi_spread);
sb.append(", rssiSpread=" + mResults[i].rssiSpread);
sb.append(", tx_rate=" + mResults[i].tx_rate);
sb.append(", txRate=" + mResults[i].txRate);
sb.append(", rxRate=" + mResults[i].rxRate);
sb.append(", rtt_ns=" + mResults[i].rtt_ns);
sb.append(", rtt=" + mResults[i].rtt);
sb.append(", rtt_sd_ns=" + mResults[i].rtt_sd_ns);
sb.append(", rttStandardDeviation=" + mResults[i].rttStandardDeviation);
sb.append(", rtt_spread_ns=" + mResults[i].rtt_spread_ns);
sb.append(", rttSpread=" + mResults[i].rttSpread);
sb.append(", distance_cm=" + mResults[i].distance_cm);
sb.append(", distance=" + mResults[i].distance);
sb.append(", distance_sd_cm=" + mResults[i].distance_sd_cm);
sb.append(", distanceStandardDeviation=" + mResults[i].distanceStandardDeviation);
sb.append(", distance_spread_cm=" + mResults[i].distance_spread_cm);
sb.append(", distanceSpread=" + mResults[i].distanceSpread);
sb.append(", burstDuration=" + mResults[i].burstDuration);
sb.append(", negotiatedBurstNum=" + mResults[i].negotiatedBurstNum);
sb.append(", LCI=" + mResults[i].LCI);
sb.append(", LCR=" + mResults[i].LCR);
sb.append(", secure=" + mResults[i].secure);
}
return sb.toString();
}
/** Implement the Parcelable interface {@hide} */
@Override
public int describeContents() {
@@ -1295,4 +1368,3 @@ public class RttManager {
}
}

View File

@@ -17,6 +17,7 @@
package android.net.wifi.nan;
import android.net.wifi.nan.ConfigRequest;
import android.net.wifi.RttManager;
/**
* Callback interface that WifiNanManager implements
@@ -28,4 +29,8 @@ oneway interface IWifiNanEventCallback
void onConnectSuccess();
void onConnectFail(int reason);
void onIdentityChanged();
void onRangingSuccess(int rangingId, in RttManager.ParcelableRttResults results);
void onRangingFailure(int rangingId, int reason, in String description);
void onRangingAborted(int rangingId);
}

View File

@@ -23,6 +23,7 @@ import android.net.wifi.nan.IWifiNanEventCallback;
import android.net.wifi.nan.IWifiNanSessionCallback;
import android.net.wifi.nan.PublishConfig;
import android.net.wifi.nan.SubscribeConfig;
import android.net.wifi.RttManager;
/**
* Interface that WifiNanService implements
@@ -51,4 +52,5 @@ interface IWifiNanManager
void sendMessage(int clientId, int sessionId, int peerId, in byte[] message, int messageLength,
int messageId);
void terminateSession(int clientId, int sessionId);
int startRanging(int clientId, int sessionId, in RttManager.ParcelableRttParams parms);
}

View File

@@ -20,6 +20,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.net.wifi.RttManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
@@ -28,10 +29,12 @@ import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
import java.lang.ref.WeakReference;
import java.util.Arrays;
/**
* This class provides the primary API for managing Wi-Fi NAN operation:
@@ -91,7 +94,7 @@ public class WifiNanManager {
private final IWifiNanManager mService;
private Object mLock = new Object(); // lock access to the following vars
private final Object mLock = new Object(); // lock access to the following vars
@GuardedBy("mLock")
private final IBinder mBinder = new Binder();
@@ -102,6 +105,9 @@ public class WifiNanManager {
@GuardedBy("mLock")
private Looper mLooper;
@GuardedBy("mLock")
private SparseArray<RttManager.RttListener> mRangingListeners = new SparseArray<>();
/**
* {@hide}
*/
@@ -237,6 +243,7 @@ public class WifiNanManager {
@Override
protected void finalize() throws Throwable {
disconnect();
super.finalize();
}
/**
@@ -415,12 +422,63 @@ public class WifiNanManager {
}
}
/**
* {@hide}
*/
public void startRanging(int sessionId, RttManager.RttParams[] params,
RttManager.RttListener listener) {
if (VDBG) {
Log.v(TAG, "startRanging: sessionId=" + sessionId + ", " + "params="
+ Arrays.toString(params) + ", listener=" + listener);
}
int clientId;
synchronized (mLock) {
if (mClientId == INVALID_CLIENT_ID) {
Log.e(TAG, "startRanging(): called with invalid client ID - not connected first?");
return;
}
clientId = mClientId;
}
int rangingKey = 0;
try {
rangingKey = mService.startRanging(clientId, sessionId,
new RttManager.ParcelableRttParams(params));
} catch (RemoteException e) {
e.rethrowAsRuntimeException();
}
synchronized (mLock) {
mRangingListeners.put(rangingKey, listener);
}
}
private static class WifiNanEventCallbackProxy extends IWifiNanEventCallback.Stub {
private static final int CALLBACK_CONNECT_SUCCESS = 0;
private static final int CALLBACK_CONNECT_FAIL = 1;
private static final int CALLBACK_IDENTITY_CHANGED = 2;
private static final int CALLBACK_RANGING_SUCCESS = 3;
private static final int CALLBACK_RANGING_FAILURE = 4;
private static final int CALLBACK_RANGING_ABORTED = 5;
private final Handler mHandler;
private final WeakReference<WifiNanManager> mNanManager;
RttManager.RttListener getAndRemoveRangingListener(int rangingId) {
WifiNanManager mgr = mNanManager.get();
if (mgr == null) {
Log.w(TAG, "getAndRemoveRangingListener: called post GC");
return null;
}
synchronized (mgr.mLock) {
RttManager.RttListener listener = mgr.mRangingListeners.get(rangingId);
mgr.mRangingListeners.delete(rangingId);
return listener;
}
}
/**
* Constructs a {@link WifiNanEventCallback} using the specified looper.
@@ -430,7 +488,7 @@ public class WifiNanManager {
*/
WifiNanEventCallbackProxy(WifiNanManager mgr, Looper looper,
final WifiNanEventCallback originalCallback) {
final WeakReference<WifiNanManager> nanManager = new WeakReference<WifiNanManager>(mgr);
mNanManager = new WeakReference<>(mgr);
if (VDBG) Log.v(TAG, "WifiNanEventCallbackProxy ctor: looper=" + looper);
mHandler = new Handler(looper) {
@@ -440,7 +498,7 @@ public class WifiNanManager {
Log.d(TAG, "WifiNanEventCallbackProxy: What=" + msg.what + ", msg=" + msg);
}
WifiNanManager mgr = nanManager.get();
WifiNanManager mgr = mNanManager.get();
if (mgr == null) {
Log.w(TAG, "WifiNanEventCallbackProxy: handleMessage post GC");
return;
@@ -455,12 +513,43 @@ public class WifiNanManager {
mgr.mLooper = null;
mgr.mClientId = INVALID_CLIENT_ID;
}
nanManager.clear();
mNanManager.clear();
originalCallback.onConnectFail(msg.arg1);
break;
case CALLBACK_IDENTITY_CHANGED:
originalCallback.onIdentityChanged();
break;
case CALLBACK_RANGING_SUCCESS: {
RttManager.RttListener listener = getAndRemoveRangingListener(msg.arg1);
if (listener == null) {
Log.e(TAG, "CALLBACK_RANGING_SUCCESS rangingId=" + msg.arg1
+ ": no listener registered (anymore)");
} else {
listener.onSuccess(
((RttManager.ParcelableRttResults) msg.obj).mResults);
}
break;
}
case CALLBACK_RANGING_FAILURE: {
RttManager.RttListener listener = getAndRemoveRangingListener(msg.arg1);
if (listener == null) {
Log.e(TAG, "CALLBACK_RANGING_SUCCESS rangingId=" + msg.arg1
+ ": no listener registered (anymore)");
} else {
listener.onFailure(msg.arg2, (String) msg.obj);
}
break;
}
case CALLBACK_RANGING_ABORTED: {
RttManager.RttListener listener = getAndRemoveRangingListener(msg.arg1);
if (listener == null) {
Log.e(TAG, "CALLBACK_RANGING_SUCCESS rangingId=" + msg.arg1
+ ": no listener registered (anymore)");
} else {
listener.onAborted();
}
break;
}
}
}
};
@@ -490,6 +579,43 @@ public class WifiNanManager {
Message msg = mHandler.obtainMessage(CALLBACK_IDENTITY_CHANGED);
mHandler.sendMessage(msg);
}
@Override
public void onRangingSuccess(int rangingId, RttManager.ParcelableRttResults results) {
if (VDBG) {
Log.v(TAG, "onRangingSuccess: rangingId=" + rangingId + ", results=" + results);
}
Message msg = mHandler.obtainMessage(CALLBACK_RANGING_SUCCESS);
msg.arg1 = rangingId;
msg.obj = results;
mHandler.sendMessage(msg);
}
@Override
public void onRangingFailure(int rangingId, int reason, String description) {
if (VDBG) {
Log.v(TAG, "onRangingSuccess: rangingId=" + rangingId + ", reason=" + reason
+ ", description=" + description);
}
Message msg = mHandler.obtainMessage(CALLBACK_RANGING_FAILURE);
msg.arg1 = rangingId;
msg.arg2 = reason;
msg.obj = description;
mHandler.sendMessage(msg);
}
@Override
public void onRangingAborted(int rangingId) {
if (VDBG) Log.v(TAG, "onRangingAborted: rangingId=" + rangingId);
Message msg = mHandler.obtainMessage(CALLBACK_RANGING_ABORTED);
msg.arg1 = rangingId;
mHandler.sendMessage(msg);
}
}
private static class WifiNanSessionCallbackProxy extends IWifiNanSessionCallback.Stub {

View File

@@ -16,6 +16,7 @@
package android.net.wifi.nan;
import android.net.wifi.RttManager;
import android.util.Log;
import java.lang.ref.WeakReference;
@@ -97,6 +98,7 @@ public class WifiNanSession {
+ "terminated so step should be done explicitly");
terminate();
}
super.finalize();
}
/**
@@ -130,4 +132,31 @@ public class WifiNanSession {
mgr.sendMessage(mSessionId, peerId, message, messageLength, messageId);
}
}
/**
* Start a ranging operation with the specified peers. The peer IDs are obtained from an
* {@link WifiNanSessionCallback#onMatch(int, byte[], int, byte[], int)} or
* {@link WifiNanSessionCallback#onMessageReceived(int, byte[], int)} operation - i.e. can only
* range devices which are part of an ongoing discovery session.
*
* @param params RTT parameters - each corresponding to a specific peer ID (the array sizes
* must be identical). The
* {@link android.net.wifi.RttManager.RttParams#bssid} member must be set to
* a peer ID - not to a MAC address.
* @param listener The listener to receive the results of the ranging session.
*/
public void startRanging(RttManager.RttParams[] params, RttManager.RttListener listener) {
if (mTerminated) {
Log.w(TAG, "startRanging: called on terminated session");
return;
} else {
WifiNanManager mgr = mMgr.get();
if (mgr == null) {
Log.w(TAG, "startRanging: called post GC on WifiNanManager");
return;
}
mgr.startRanging(mSessionId, params, listener);
}
}
}