blob: 83ad2ba34f513fbefcb420ba03681dd219d20166 [file] [log] [blame]
/*
* Copyright 2022 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 com.android.server.uwb;
import static com.android.server.uwb.data.UwbUciConstants.RANGING_MEASUREMENT_TYPE_OWR_AOA;
import static com.android.server.uwb.data.UwbUciConstants.RANGING_MEASUREMENT_TYPE_TWO_WAY;
import static com.android.server.uwb.util.UwbUtil.convertFloatToQFormat;
import static com.android.server.uwb.util.UwbUtil.degreeToRadian;
import android.os.PersistableBundle;
import android.util.Pair;
import android.uwb.AngleMeasurement;
import android.uwb.AngleOfArrivalMeasurement;
import android.uwb.DistanceMeasurement;
import android.uwb.RangingMeasurement;
import android.uwb.RangingReport;
import android.uwb.UwbAddress;
import com.android.server.uwb.data.UwbOwrAoaMeasurement;
import com.android.server.uwb.data.UwbRangingData;
import com.android.server.uwb.data.UwbTwoWayMeasurement;
import com.android.server.uwb.params.TlvUtil;
import com.google.uwb.support.fira.FiraParams;
import com.google.uwb.support.oemextension.RangingReportMetadata;
public class UwbTestUtils {
public static final int TEST_SESSION_ID = 7;
public static final int TEST_SESSION_ID_2 = 8;
public static final byte[] PEER_SHORT_MAC_ADDRESS = {0x1, 0x3};
public static final byte[] PEER_EXTENDED_MAC_ADDRESS =
new byte[] {0x12, 0x14, 0x16, 0x18, 0x31, 0x33, 0x35, 0x37};
public static final byte[] PEER_EXTENDED_MAC_ADDRESS_REVERSE_BYTES =
new byte[] {0x37, 0x35, 0x33, 0x31, 0x18, 0x16, 0x14, 0x12};
public static final byte[] PEER_EXTENDED_MAC_ADDRESS_2 =
new byte[] {0x2, 0x4, 0x6, 0x8, 0x1, 0x3, 0x5, 0x7};
public static final byte[] PEER_BAD_MAC_ADDRESS = new byte[] {0x12, 0x14, 0x16, 0x18};
public static final byte[] PEER_EXTENDED_SHORT_MAC_ADDRESS =
new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x37};
public static final UwbAddress PEER_UWB_ADDRESS = UwbAddress.fromBytes(
PEER_EXTENDED_MAC_ADDRESS_REVERSE_BYTES);
public static final PersistableBundle PERSISTABLE_BUNDLE = new PersistableBundle();
public static final byte[] DATA_PAYLOAD = new byte[] {0x13, 0x15, 0x18};
private static final long TEST_SEQ_COUNTER = 5;
private static final int TEST_RCR_INDICATION = 7;
private static final long TEST_CURR_RANGING_INTERVAL = 100;
private static final int TEST_RANGING_MEASURES_TYPE = RANGING_MEASUREMENT_TYPE_TWO_WAY;
private static final int TEST_MAC_ADDRESS_MODE = 1;
private static final int TEST_STATUS = FiraParams.STATUS_CODE_OK;
private static final int TEST_LOS = 0;
private static final int TEST_DISTANCE = 101;
private static final float TEST_AOA_AZIMUTH = 67;
private static final int TEST_AOA_AZIMUTH_FOM = 50;
private static final float TEST_AOA_ELEVATION = 37;
private static final int TEST_AOA_ELEVATION_FOM = 90;
private static final float TEST_AOA_DEST_AZIMUTH = 67;
private static final int TEST_AOA_DEST_AZIMUTH_FOM = 50;
private static final float TEST_AOA_DEST_ELEVATION = 37;
private static final int TEST_AOA_DEST_ELEVATION_FOM = 90;
private static final int TEST_FRAME_SEQUENCE_NUMBER = 1;
private static final int TEST_BLOCK_IDX = 100;
private static final int TEST_SLOT_IDX = 10;
private static final int TEST_RSSI = 150;
private UwbTestUtils() {}
/** Build UwbRangingData for all Ranging Measurement Type(s). */
public static UwbRangingData generateRangingData(
int rangingMeasurementType, int rangingStatus) {
switch (rangingMeasurementType) {
case RANGING_MEASUREMENT_TYPE_TWO_WAY:
return generateTwoWayMeasurementRangingData(rangingStatus);
case RANGING_MEASUREMENT_TYPE_OWR_AOA:
return generateOwrAoaMeasurementRangingData(rangingStatus);
default:
return null;
}
}
private static UwbRangingData generateTwoWayMeasurementRangingData(int rangingStatus) {
final int noOfRangingMeasures = 1;
final UwbTwoWayMeasurement[] uwbTwoWayMeasurements =
new UwbTwoWayMeasurement[noOfRangingMeasures];
uwbTwoWayMeasurements[0] = new UwbTwoWayMeasurement(PEER_SHORT_MAC_ADDRESS, rangingStatus,
TEST_LOS, TEST_DISTANCE, convertFloatToQFormat(TEST_AOA_AZIMUTH, 9, 7),
TEST_AOA_AZIMUTH_FOM, convertFloatToQFormat(TEST_AOA_ELEVATION, 9, 7),
TEST_AOA_ELEVATION_FOM, convertFloatToQFormat(TEST_AOA_DEST_AZIMUTH, 9, 7),
TEST_AOA_DEST_AZIMUTH_FOM, convertFloatToQFormat(TEST_AOA_DEST_ELEVATION, 9, 7),
TEST_AOA_DEST_ELEVATION_FOM, TEST_SLOT_IDX, TEST_RSSI);
return new UwbRangingData(TEST_SEQ_COUNTER, TEST_SESSION_ID,
TEST_RCR_INDICATION, TEST_CURR_RANGING_INTERVAL, RANGING_MEASUREMENT_TYPE_TWO_WAY,
TEST_MAC_ADDRESS_MODE, noOfRangingMeasures, uwbTwoWayMeasurements, new byte[0]);
}
private static UwbRangingData generateOwrAoaMeasurementRangingData(int rangingStatus) {
final int noOfRangingMeasures = 1;
final UwbOwrAoaMeasurement uwbOwrAoaMeasurement = new UwbOwrAoaMeasurement(
PEER_EXTENDED_MAC_ADDRESS, rangingStatus, TEST_LOS,
TEST_FRAME_SEQUENCE_NUMBER, TEST_BLOCK_IDX,
convertFloatToQFormat(TEST_AOA_AZIMUTH, 9, 7), TEST_AOA_AZIMUTH_FOM,
convertFloatToQFormat(TEST_AOA_ELEVATION, 9, 7), TEST_AOA_ELEVATION_FOM);
return new UwbRangingData(TEST_SEQ_COUNTER, TEST_SESSION_ID,
TEST_RCR_INDICATION, TEST_CURR_RANGING_INTERVAL, RANGING_MEASUREMENT_TYPE_OWR_AOA,
TEST_MAC_ADDRESS_MODE, noOfRangingMeasures, uwbOwrAoaMeasurement);
}
// Helper method to generate a UwbRangingData instance and corresponding RangingMeasurement
public static Pair<UwbRangingData, RangingReport> generateRangingDataAndRangingReport(
byte[] macAddress, int rangingMeasurementType,
boolean isAoaAzimuthEnabled, boolean isAoaElevationEnabled,
boolean isDestAoaAzimuthEnabled, boolean isDestAoaElevationEnabled,
long elapsedRealtimeNanos) {
UwbRangingData uwbRangingData = generateRangingData(rangingMeasurementType, TEST_STATUS);
// TODO(b/246678053): Add rawNtfData[] for both TwoWay and OWR AoA Measurements..
PersistableBundle rangingReportMetadata = new RangingReportMetadata.Builder()
.setSessionId(0)
.build()
.toBundle();
AngleOfArrivalMeasurement aoaMeasurement = null;
AngleOfArrivalMeasurement aoaDestMeasurement = null;
if (isAoaAzimuthEnabled || isAoaElevationEnabled) {
AngleMeasurement aoaAzimuth = null;
AngleMeasurement aoaElevation = null;
AngleOfArrivalMeasurement.Builder aoaBuilder = null;
if (isAoaAzimuthEnabled) {
aoaAzimuth = new AngleMeasurement(
degreeToRadian(TEST_AOA_AZIMUTH), 0,
TEST_AOA_AZIMUTH_FOM / (double) 100);
aoaBuilder = new AngleOfArrivalMeasurement.Builder(aoaAzimuth);
}
if (isAoaElevationEnabled && aoaBuilder != null) {
aoaElevation = new AngleMeasurement(
degreeToRadian(TEST_AOA_ELEVATION), 0,
TEST_AOA_ELEVATION_FOM / (double) 100);
aoaBuilder.setAltitude(aoaElevation);
}
aoaMeasurement = (aoaBuilder != null) ? aoaBuilder.build() : null;
}
if (isDestAoaAzimuthEnabled || isDestAoaElevationEnabled) {
AngleMeasurement aoaDestAzimuth = null;
AngleMeasurement aoaDestElevation = null;
AngleOfArrivalMeasurement.Builder aoaBuilder = null;
if (isDestAoaAzimuthEnabled) {
aoaDestAzimuth =
new AngleMeasurement(
degreeToRadian(TEST_AOA_DEST_AZIMUTH), 0,
TEST_AOA_DEST_AZIMUTH_FOM / (double) 100);
aoaBuilder = new AngleOfArrivalMeasurement.Builder(aoaDestAzimuth);
}
if (isDestAoaElevationEnabled && aoaBuilder != null) {
aoaDestElevation =
new AngleMeasurement(
degreeToRadian(TEST_AOA_DEST_ELEVATION), 0,
TEST_AOA_DEST_ELEVATION_FOM / (double) 100);
aoaBuilder.setAltitude(aoaDestElevation);
}
aoaDestMeasurement = (aoaBuilder != null) ? aoaBuilder.build() : null;
}
RangingReport rangingReport = buildRangingReport(macAddress, rangingMeasurementType,
aoaMeasurement, aoaDestMeasurement, elapsedRealtimeNanos, rangingReportMetadata);
return Pair.create(uwbRangingData, rangingReport);
}
private static RangingReport buildRangingReport(byte[] macAddress, int rangingMeasurementType,
AngleOfArrivalMeasurement aoaMeasurement, AngleOfArrivalMeasurement aoaDestMeasurement,
long elapsedRealtimeNanos, PersistableBundle rangingReportMetadata) {
PersistableBundle rangingMeasurementMetadata = new PersistableBundle();
RangingMeasurement.Builder rangingMeasurementBuilder = new RangingMeasurement.Builder()
.setRemoteDeviceAddress(UwbAddress.fromBytes(
TlvUtil.getReverseBytes(macAddress)))
.setStatus(TEST_STATUS)
.setElapsedRealtimeNanos(elapsedRealtimeNanos)
.setAngleOfArrivalMeasurement(aoaMeasurement)
.setLineOfSight(TEST_LOS);
if (rangingMeasurementType == RANGING_MEASUREMENT_TYPE_TWO_WAY) {
rangingMeasurementBuilder
.setDistanceMeasurement(
new DistanceMeasurement.Builder()
.setMeters(TEST_DISTANCE / (double) 100)
.setErrorMeters(0)
.setConfidenceLevel(0)
.build())
.setDestinationAngleOfArrivalMeasurement(aoaDestMeasurement)
.setRssiDbm(-TEST_RSSI / 2)
.setRangingMeasurementMetadata(rangingMeasurementMetadata);
}
return new RangingReport.Builder()
.addMeasurement(rangingMeasurementBuilder.build())
.addRangingReportMetadata(rangingReportMetadata)
.build();
}
}