blob: 918803ef2018866f9bf13311c062d8c5722c5156 [file] [log] [blame]
/*
* Copyright (C) 2017 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 android.net.wifi.rtt;
import android.os.Handler;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
import libcore.util.HexEncoding;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
/**
* Ranging result for a request started by
* {@link WifiRttManager#startRanging(RangingRequest, RangingResultCallback, Handler)}. Results are
* returned in {@link RangingResultCallback#onRangingResults(List)}.
* <p>
* A ranging result is the distance measurement result for a single device specified in the
* {@link RangingRequest}.
*
* @hide RTT_API
*/
public final class RangingResult implements Parcelable {
private static final String TAG = "RangingResult";
private final int mStatus;
private final byte[] mMac;
private final int mDistanceCm;
private final int mDistanceStdDevCm;
private final int mRssi;
private final long mTimestamp;
/** @hide */
public RangingResult(int status, byte[] mac, int distanceCm, int distanceStdDevCm, int rssi,
long timestamp) {
mStatus = status;
mMac = mac;
mDistanceCm = distanceCm;
mDistanceStdDevCm = distanceStdDevCm;
mRssi = rssi;
mTimestamp = timestamp;
}
/**
* @return The status of ranging measurement: {@link RangingResultCallback#STATUS_SUCCESS} in
* case of success, and {@link RangingResultCallback#STATUS_FAIL} in case of failure.
*/
public int getStatus() {
return mStatus;
}
/**
* @return The MAC address of the device whose range measurement was requested. Will correspond
* to the MAC address of the device in the {@link RangingRequest}.
* <p>
* Always valid (i.e. when {@link #getStatus()} is either SUCCESS or FAIL.
*/
public byte[] getMacAddress() {
return mMac;
}
/**
* @return The distance (in cm) to the device specified by {@link #getMacAddress()}.
* <p>
* Only valid if {@link #getStatus()} returns {@link RangingResultCallback#STATUS_SUCCESS}.
*/
public int getDistanceCm() {
if (mStatus != RangingResultCallback.STATUS_SUCCESS) {
Log.e(TAG, "getDistanceCm(): invalid value retrieved");
}
return mDistanceCm;
}
/**
* @return The standard deviation of the measured distance (in cm) to the device specified by
* {@link #getMacAddress()}. The standard deviation is calculated over the measurements
* executed in a single RTT burst.
* <p>
* Only valid if {@link #getStatus()} returns {@link RangingResultCallback#STATUS_SUCCESS}.
*/
public int getDistanceStdDevCm() {
if (mStatus != RangingResultCallback.STATUS_SUCCESS) {
Log.e(TAG, "getDistanceStdDevCm(): invalid value retrieved");
}
return mDistanceStdDevCm;
}
/**
* @return The average RSSI (in units of -0.5dB) observed during the RTT measurement.
* <p>
* Only valid if {@link #getStatus()} returns {@link RangingResultCallback#STATUS_SUCCESS}.
*/
public int getRssi() {
if (mStatus != RangingResultCallback.STATUS_SUCCESS) {
// TODO: should this be an exception?
Log.e(TAG, "getRssi(): invalid value retrieved");
}
return mRssi;
}
/**
* @return The timestamp (in us) at which the ranging operation was performed
* <p>
* Only valid if {@link #getStatus()} returns {@link RangingResultCallback#STATUS_SUCCESS}.
*/
public long getRangingTimestamp() {
return mTimestamp;
}
/** @hide */
@Override
public int describeContents() {
return 0;
}
/** @hide */
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mStatus);
dest.writeByteArray(mMac);
dest.writeInt(mDistanceCm);
dest.writeInt(mDistanceStdDevCm);
dest.writeInt(mRssi);
dest.writeLong(mTimestamp);
}
/** @hide */
public static final Creator<RangingResult> CREATOR = new Creator<RangingResult>() {
@Override
public RangingResult[] newArray(int size) {
return new RangingResult[size];
}
@Override
public RangingResult createFromParcel(Parcel in) {
int status = in.readInt();
byte[] mac = in.createByteArray();
int distanceCm = in.readInt();
int distanceStdDevCm = in.readInt();
int rssi = in.readInt();
long timestamp = in.readLong();
return new RangingResult(status, mac, distanceCm, distanceStdDevCm, rssi, timestamp);
}
};
/** @hide */
@Override
public String toString() {
return new StringBuilder("RangingResult: [status=").append(mStatus).append(", mac=").append(
mMac == null ? "<null>" : HexEncoding.encodeToString(mMac)).append(
", distanceCm=").append(mDistanceCm).append(", distanceStdDevCm=").append(
mDistanceStdDevCm).append(", rssi=").append(mRssi).append(", timestamp=").append(
mTimestamp).append("]").toString();
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof RangingResult)) {
return false;
}
RangingResult lhs = (RangingResult) o;
return mStatus == lhs.mStatus && Arrays.equals(mMac, lhs.mMac)
&& mDistanceCm == lhs.mDistanceCm && mDistanceStdDevCm == lhs.mDistanceStdDevCm
&& mRssi == lhs.mRssi && mTimestamp == lhs.mTimestamp;
}
@Override
public int hashCode() {
return Objects.hash(mStatus, mMac, mDistanceCm, mDistanceStdDevCm, mRssi, mTimestamp);
}
}