1 /* 2 * Copyright 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.uwb; 18 19 import static com.android.server.uwb.data.UwbUciConstants.MAC_ADDRESSING_MODE_SHORT; 20 import static com.android.server.uwb.data.UwbUciConstants.RANGING_MEASUREMENT_TYPE_DL_TDOA; 21 import static com.android.server.uwb.data.UwbUciConstants.RANGING_MEASUREMENT_TYPE_OWR_AOA; 22 import static com.android.server.uwb.data.UwbUciConstants.RANGING_MEASUREMENT_TYPE_TWO_WAY; 23 import static com.android.server.uwb.util.UwbUtil.convertFloatToQFormat; 24 import static com.android.server.uwb.util.UwbUtil.degreeToRadian; 25 26 import static com.google.uwb.support.radar.RadarParams.BITS_PER_SAMPLES_48; 27 import static com.google.uwb.support.radar.RadarParams.RADAR_DATA_TYPE_RADAR_SWEEP_SAMPLES; 28 29 import android.os.PersistableBundle; 30 import android.util.Pair; 31 import android.uwb.AngleMeasurement; 32 import android.uwb.AngleOfArrivalMeasurement; 33 import android.uwb.DistanceMeasurement; 34 import android.uwb.RangingMeasurement; 35 import android.uwb.RangingReport; 36 import android.uwb.UwbAddress; 37 38 import com.android.modules.utils.build.SdkLevel; 39 import com.android.server.uwb.data.UwbDlTDoAMeasurement; 40 import com.android.server.uwb.data.UwbOwrAoaMeasurement; 41 import com.android.server.uwb.data.UwbRadarData; 42 import com.android.server.uwb.data.UwbRadarSweepData; 43 import com.android.server.uwb.data.UwbRangingData; 44 import com.android.server.uwb.data.UwbTwoWayMeasurement; 45 import com.android.server.uwb.params.TlvUtil; 46 47 import com.google.uwb.support.dltdoa.DlTDoAMeasurement; 48 import com.google.uwb.support.fira.FiraParams; 49 import com.google.uwb.support.oemextension.RangingReportMetadata; 50 import com.google.uwb.support.radar.RadarData; 51 import com.google.uwb.support.radar.RadarParams; 52 import com.google.uwb.support.radar.RadarSweepData; 53 54 public class UwbTestUtils { 55 public static final int TEST_SESSION_ID = 7; 56 public static final int TEST_SESSION_ID_2 = 8; 57 public static final byte TEST_SESSION_TYPE = FiraParams.SESSION_TYPE_RANGING; 58 public static final byte[] PEER_SHORT_MAC_ADDRESS = {0x35, 0x37}; 59 public static final long PEER_SHORT_MAC_ADDRESS_LONG = 0x3735L; 60 public static final byte[] PEER_EXTENDED_SHORT_MAC_ADDRESS = 61 {0x35, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 62 public static final long PEER_EXTENDED_SHORT_MAC_ADDRESS_LONG = 0x3735L; 63 public static final byte[] PEER_EXTENDED_MAC_ADDRESS = 64 {0x12, 0x14, 0x16, 0x18, 0x31, 0x33, 0x35, 0x37}; 65 public static final long PEER_EXTENDED_MAC_ADDRESS_LONG = 0x3735333118161412L; 66 public static final byte[] PEER_EXTENDED_MAC_ADDRESS_2 = 67 {0x2, 0x4, 0x6, 0x8, 0x1, 0x3, 0x5, 0x7}; 68 public static final long PEER_EXTENDED_MAC_ADDRESS_2_LONG = 0x0705030108060402L; 69 public static final byte[] PEER_BAD_MAC_ADDRESS = {0x12, 0x14, 0x16, 0x18}; 70 public static final UwbAddress PEER_EXTENDED_UWB_ADDRESS = UwbAddress.fromBytes( 71 PEER_EXTENDED_MAC_ADDRESS); 72 public static final UwbAddress PEER_EXTENDED_UWB_ADDRESS_2 = UwbAddress.fromBytes( 73 PEER_EXTENDED_MAC_ADDRESS_2); 74 public static final UwbAddress PEER_SHORT_UWB_ADDRESS = UwbAddress.fromBytes( 75 PEER_SHORT_MAC_ADDRESS); 76 public static final UwbAddress PEER_EXTENDED_SHORT_UWB_ADDRESS = UwbAddress.fromBytes( 77 PEER_EXTENDED_SHORT_MAC_ADDRESS); 78 79 public static final PersistableBundle PERSISTABLE_BUNDLE = new PersistableBundle(); 80 public static final byte[] DATA_PAYLOAD = new byte[] {0x13, 0x15, 0x18}; 81 public static final int RANGING_MEASUREMENT_TYPE_UNDEFINED = 0; // RFU in spec 82 public static final int MAX_DATA_SIZE = 100; 83 84 private static final byte[] TEST_RAW_NTF_DATA = {0x10, 0x01, 0x05}; 85 private static final long TEST_SEQ_COUNTER = 5; 86 private static final long TEST_SEQ_COUNTER2 = 6; 87 private static final int TEST_RCR_INDICATION = 7; 88 private static final long TEST_CURR_RANGING_INTERVAL = 100; 89 private static final int TEST_RANGING_MEASURES_TYPE = RANGING_MEASUREMENT_TYPE_TWO_WAY; 90 private static final long TEST_HUS_PRIMARY_SESSION_ID = 0; 91 private static final int TEST_MAC_ADDRESS_MODE = 1; 92 public static final int TEST_STATUS = FiraParams.STATUS_CODE_OK; 93 private static final int TEST_LOS = 0; 94 private static final int TEST_DISTANCE = 101; 95 private static final float TEST_AOA_AZIMUTH = 67; 96 private static final int TEST_AOA_AZIMUTH_FOM = 50; 97 private static final int TEST_BAD_AOA_AZIMUTH_FOM = 150; 98 private static final float TEST_AOA_ELEVATION = 37; 99 private static final int TEST_AOA_ELEVATION_FOM = 90; 100 private static final float TEST_AOA_DEST_AZIMUTH = 67; 101 private static final int TEST_AOA_DEST_AZIMUTH_FOM = 50; 102 private static final float TEST_AOA_DEST_ELEVATION = 37; 103 private static final int TEST_AOA_DEST_ELEVATION_FOM = 90; 104 private static final int TEST_FRAME_SEQUENCE_NUMBER = 1; 105 private static final int TEST_BLOCK_IDX = 100; 106 private static final int TEST_SLOT_IDX = 10; 107 private static final int TEST_MESSAGE_TYPE = 1; 108 private static final int TEST_MESSAGE_CONTROL = 1331; 109 private static final int TEST_BLOCK_INDEX = 5; 110 private static final int TEST_ROUND_INDEX = 1; 111 private static final long TEST_TIMESTAMP = 500_000L; 112 private static final long TEST_TIMESTAMP2 = 600_000L; 113 private static final float TEST_ANCHOR_CFO = 12.50f; 114 private static final float TEST_CFO = 15.50f; 115 private static final long TEST_INTIATOR_REPLY_TIME = 500_000L; 116 private static final long TEST_RESPONDER_REPLY_TIME = 300_000L; 117 private static final int TEST_INITIATOR_RESPONDER_TOF = 500; 118 private static final byte[] TEST_ANCHOR_LOCATION = {0x01, 0x02, 0x03, 0x04, 119 0x05, 0x06, 0x07, 0x08, 0x09, 0x10}; 120 private static final byte[] TEST_ACTIVE_RANGING_ROUNDS = {0x02, 0x08}; 121 private static final int TEST_RSSI = 150; 122 123 private static final int TEST_SAMPLES_PER_SWEEP = 64; 124 private static final int TEST_BITS_PER_SAMPLE = BITS_PER_SAMPLES_48; 125 private static final int TEST_SWEEP_OFFSET = -10; 126 private static final byte[] TEST_VENDOR_SPECIFIC_DATA = {0x04, 0x07}; 127 private static final byte[] TEST_SAMPLE_DATA = {0x06, 0x08, (byte) 0Xff}; 128 UwbTestUtils()129 private UwbTestUtils() {} 130 131 /** Build UwbRangingData for all Ranging Measurement Type(s). */ generateRangingData( int rangingMeasurementType, int macAddressingMode, int rangingStatus)132 public static UwbRangingData generateRangingData( 133 int rangingMeasurementType, int macAddressingMode, int rangingStatus) { 134 byte[] macAddress = (macAddressingMode == MAC_ADDRESSING_MODE_SHORT) 135 ? PEER_SHORT_MAC_ADDRESS : PEER_EXTENDED_MAC_ADDRESS; 136 return generateRangingData( 137 rangingMeasurementType, macAddressingMode, macAddress, rangingStatus); 138 } 139 140 /** Build UwbRangingData for all Ranging Measurement Type(s). */ generateRangingData( int rangingMeasurementType, int macAddressingMode, byte[] macAddress, int rangingStatus)141 public static UwbRangingData generateRangingData( 142 int rangingMeasurementType, int macAddressingMode, byte[] macAddress, 143 int rangingStatus) { 144 switch (rangingMeasurementType) { 145 case RANGING_MEASUREMENT_TYPE_TWO_WAY: 146 return generateTwoWayMeasurementRangingData(rangingStatus); 147 case RANGING_MEASUREMENT_TYPE_OWR_AOA: 148 return generateOwrAoaMeasurementRangingData( 149 macAddressingMode, macAddress, rangingStatus); 150 case RANGING_MEASUREMENT_TYPE_DL_TDOA: 151 return generateDlTDoAMeasurementRangingData(macAddressingMode, rangingStatus); 152 default: 153 return generateDefaultRangingData(); 154 } 155 } 156 generateTwoWayMeasurementRangingData(int rangingStatus)157 private static UwbRangingData generateTwoWayMeasurementRangingData(int rangingStatus) { 158 final int noOfRangingMeasures = 1; 159 final UwbTwoWayMeasurement[] uwbTwoWayMeasurements = 160 new UwbTwoWayMeasurement[noOfRangingMeasures]; 161 uwbTwoWayMeasurements[0] = new UwbTwoWayMeasurement(PEER_SHORT_MAC_ADDRESS, rangingStatus, 162 TEST_LOS, TEST_DISTANCE, convertFloatToQFormat(TEST_AOA_AZIMUTH, 9, 7), 163 TEST_AOA_AZIMUTH_FOM, convertFloatToQFormat(TEST_AOA_ELEVATION, 9, 7), 164 TEST_AOA_ELEVATION_FOM, convertFloatToQFormat(TEST_AOA_DEST_AZIMUTH, 9, 7), 165 TEST_AOA_DEST_AZIMUTH_FOM, convertFloatToQFormat(TEST_AOA_DEST_ELEVATION, 9, 7), 166 TEST_AOA_DEST_ELEVATION_FOM, TEST_SLOT_IDX, TEST_RSSI); 167 return new UwbRangingData(TEST_SEQ_COUNTER, TEST_SESSION_ID, 168 TEST_RCR_INDICATION, TEST_CURR_RANGING_INTERVAL, RANGING_MEASUREMENT_TYPE_TWO_WAY, 169 TEST_HUS_PRIMARY_SESSION_ID, TEST_MAC_ADDRESS_MODE, noOfRangingMeasures, 170 uwbTwoWayMeasurements, TEST_RAW_NTF_DATA); 171 } 172 generateOwrAoaMeasurementRangingData( int macAddressingMode, byte[] macAddress, int rangingStatus)173 private static UwbRangingData generateOwrAoaMeasurementRangingData( 174 int macAddressingMode, byte[] macAddress, int rangingStatus) { 175 final int noOfRangingMeasures = 1; 176 final UwbOwrAoaMeasurement uwbOwrAoaMeasurement = new UwbOwrAoaMeasurement( 177 macAddress, rangingStatus, TEST_LOS, 178 TEST_FRAME_SEQUENCE_NUMBER, TEST_BLOCK_IDX, 179 convertFloatToQFormat(TEST_AOA_AZIMUTH, 9, 7), TEST_AOA_AZIMUTH_FOM, 180 convertFloatToQFormat(TEST_AOA_ELEVATION, 9, 7), TEST_AOA_ELEVATION_FOM); 181 return new UwbRangingData(TEST_SEQ_COUNTER, TEST_SESSION_ID, 182 TEST_RCR_INDICATION, TEST_CURR_RANGING_INTERVAL, RANGING_MEASUREMENT_TYPE_OWR_AOA, 183 TEST_HUS_PRIMARY_SESSION_ID, macAddressingMode, noOfRangingMeasures, 184 uwbOwrAoaMeasurement, TEST_RAW_NTF_DATA); 185 } 186 187 /** Generate an OWR ranging data with a bad AoA Azimuth FOM */ generateBadOwrAoaMeasurementRangingData( int macAddressingMode, byte[] macAddress)188 public static UwbRangingData generateBadOwrAoaMeasurementRangingData( 189 int macAddressingMode, byte[] macAddress) { 190 final int noOfRangingMeasures = 1; 191 final UwbOwrAoaMeasurement uwbOwrAoaMeasurement = new UwbOwrAoaMeasurement( 192 macAddress, TEST_STATUS, TEST_LOS, 193 TEST_FRAME_SEQUENCE_NUMBER, TEST_BLOCK_IDX, 194 convertFloatToQFormat(TEST_AOA_AZIMUTH, 9, 7), TEST_BAD_AOA_AZIMUTH_FOM, 195 convertFloatToQFormat(TEST_AOA_ELEVATION, 9, 7), TEST_AOA_ELEVATION_FOM); 196 return new UwbRangingData(TEST_SEQ_COUNTER, TEST_SESSION_ID, 197 TEST_RCR_INDICATION, TEST_CURR_RANGING_INTERVAL, RANGING_MEASUREMENT_TYPE_OWR_AOA, 198 TEST_HUS_PRIMARY_SESSION_ID, macAddressingMode, noOfRangingMeasures, 199 uwbOwrAoaMeasurement, TEST_RAW_NTF_DATA); 200 } 201 generateDlTDoAMeasurementRangingData( int macAddressingMode, int rangingStatus)202 private static UwbRangingData generateDlTDoAMeasurementRangingData( 203 int macAddressingMode, int rangingStatus) { 204 final int noOfRangingMeasures = 1; 205 byte[] macAddress = (macAddressingMode == MAC_ADDRESSING_MODE_SHORT) 206 ? PEER_SHORT_MAC_ADDRESS : PEER_EXTENDED_MAC_ADDRESS; 207 final UwbDlTDoAMeasurement[] uwbDlTDoAMeasurements = 208 new UwbDlTDoAMeasurement[noOfRangingMeasures]; 209 uwbDlTDoAMeasurements[0] = new UwbDlTDoAMeasurement(macAddress, rangingStatus, 210 TEST_MESSAGE_TYPE, TEST_MESSAGE_CONTROL, TEST_BLOCK_INDEX, TEST_ROUND_INDEX, 211 TEST_LOS, convertFloatToQFormat(TEST_AOA_AZIMUTH, 9, 7), 212 TEST_AOA_AZIMUTH_FOM, convertFloatToQFormat(TEST_AOA_ELEVATION, 9, 7), 213 TEST_AOA_ELEVATION_FOM, TEST_RSSI, TEST_TIMESTAMP, TEST_TIMESTAMP, 214 convertFloatToQFormat(TEST_ANCHOR_CFO, 6, 10), 215 convertFloatToQFormat(TEST_CFO, 6, 10), TEST_INTIATOR_REPLY_TIME, 216 TEST_RESPONDER_REPLY_TIME, TEST_INITIATOR_RESPONDER_TOF, TEST_ANCHOR_LOCATION, 217 TEST_ACTIVE_RANGING_ROUNDS); 218 219 return new UwbRangingData(TEST_SEQ_COUNTER, TEST_SESSION_ID, 220 TEST_RCR_INDICATION, TEST_CURR_RANGING_INTERVAL, RANGING_MEASUREMENT_TYPE_DL_TDOA, 221 TEST_HUS_PRIMARY_SESSION_ID, macAddressingMode, noOfRangingMeasures, 222 uwbDlTDoAMeasurements, TEST_RAW_NTF_DATA); 223 } 224 225 // Create a UwbRangingData with no measurements, for negative test cases (example: incorrect 226 // ranging measurement type). generateDefaultRangingData()227 private static UwbRangingData generateDefaultRangingData() { 228 final int noOfRangingMeasures = 0; 229 final UwbTwoWayMeasurement[] uwbEmptyTwoWayMeasurements = 230 new UwbTwoWayMeasurement[noOfRangingMeasures]; 231 return new UwbRangingData(TEST_SEQ_COUNTER, TEST_SESSION_ID, 232 TEST_RCR_INDICATION, TEST_CURR_RANGING_INTERVAL, RANGING_MEASUREMENT_TYPE_UNDEFINED, 233 TEST_HUS_PRIMARY_SESSION_ID, TEST_MAC_ADDRESS_MODE, noOfRangingMeasures, 234 uwbEmptyTwoWayMeasurements, TEST_RAW_NTF_DATA); 235 } 236 237 // Helper method to generate a UwbRangingData instance and corresponding RangingMeasurement generateRangingDataAndRangingReport( byte[] macAddress, int macAddressingMode, int rangingMeasurementType, boolean isAoaAzimuthEnabled, boolean isAoaElevationEnabled, boolean isDestAoaAzimuthEnabled, boolean isDestAoaElevationEnabled, long elapsedRealtimeNanos)238 public static Pair<UwbRangingData, RangingReport> generateRangingDataAndRangingReport( 239 byte[] macAddress, int macAddressingMode, int rangingMeasurementType, 240 boolean isAoaAzimuthEnabled, boolean isAoaElevationEnabled, 241 boolean isDestAoaAzimuthEnabled, boolean isDestAoaElevationEnabled, 242 long elapsedRealtimeNanos) { 243 UwbRangingData uwbRangingData = generateRangingData(rangingMeasurementType, 244 macAddressingMode, TEST_STATUS); 245 246 PersistableBundle rangingReportMetadata = new RangingReportMetadata.Builder() 247 .setSessionId(0) 248 .setRawNtfData(new byte[] {0x10, 0x01, 0x05}) 249 .build() 250 .toBundle(); 251 252 AngleOfArrivalMeasurement aoaMeasurement = null; 253 AngleOfArrivalMeasurement aoaDestMeasurement = null; 254 if (isAoaAzimuthEnabled || isAoaElevationEnabled) { 255 AngleMeasurement aoaAzimuth = isAoaAzimuthEnabled 256 ? new AngleMeasurement(degreeToRadian(TEST_AOA_AZIMUTH), 0, 257 TEST_AOA_AZIMUTH_FOM / (double) 100) 258 : new AngleMeasurement(0, 0, 0); 259 AngleOfArrivalMeasurement.Builder aoaBuilder = 260 new AngleOfArrivalMeasurement.Builder(aoaAzimuth); 261 262 if (isAoaElevationEnabled) { 263 AngleMeasurement aoaElevation = new AngleMeasurement( 264 degreeToRadian(TEST_AOA_ELEVATION), 0, 265 TEST_AOA_ELEVATION_FOM / (double) 100); 266 aoaBuilder.setAltitude(aoaElevation); 267 } 268 269 aoaMeasurement = aoaBuilder.build(); 270 } 271 if (isDestAoaAzimuthEnabled || isDestAoaElevationEnabled) { 272 AngleMeasurement aoaAzimuth = isDestAoaAzimuthEnabled 273 ? new AngleMeasurement(degreeToRadian(TEST_AOA_DEST_AZIMUTH), 0, 274 TEST_AOA_DEST_AZIMUTH_FOM / (double) 100) 275 : new AngleMeasurement(0, 0, 0); 276 AngleOfArrivalMeasurement.Builder aoaBuilder = 277 new AngleOfArrivalMeasurement.Builder(aoaAzimuth); 278 279 if (isDestAoaElevationEnabled) { 280 AngleMeasurement aoaElevation = new AngleMeasurement( 281 degreeToRadian(TEST_AOA_DEST_ELEVATION), 0, 282 TEST_AOA_DEST_ELEVATION_FOM / (double) 100); 283 aoaBuilder.setAltitude(aoaElevation); 284 } 285 286 aoaDestMeasurement = aoaBuilder.build(); 287 } 288 289 RangingReport rangingReport = buildRangingReport(macAddress, rangingMeasurementType, 290 aoaMeasurement, aoaDestMeasurement, elapsedRealtimeNanos, rangingReportMetadata); 291 return Pair.create(uwbRangingData, rangingReport); 292 } 293 getComputedMacAddress(byte[] address)294 private static UwbAddress getComputedMacAddress(byte[] address) { 295 if (!SdkLevel.isAtLeastU()) { 296 return UwbAddress.fromBytes(TlvUtil.getReverseBytes(address)); 297 } 298 return UwbAddress.fromBytes(address); 299 } 300 buildRangingReport(byte[] macAddress, int rangingMeasurementType, AngleOfArrivalMeasurement aoaMeasurement, AngleOfArrivalMeasurement aoaDestMeasurement, long elapsedRealtimeNanos, PersistableBundle rangingReportMetadata)301 private static RangingReport buildRangingReport(byte[] macAddress, int rangingMeasurementType, 302 AngleOfArrivalMeasurement aoaMeasurement, AngleOfArrivalMeasurement aoaDestMeasurement, 303 long elapsedRealtimeNanos, PersistableBundle rangingReportMetadata) { 304 305 PersistableBundle rangingMeasurementMetadata = new PersistableBundle(); 306 307 RangingMeasurement.Builder rangingMeasurementBuilder = new RangingMeasurement.Builder() 308 .setRemoteDeviceAddress(getComputedMacAddress(macAddress)) 309 .setStatus(TEST_STATUS) 310 .setElapsedRealtimeNanos(elapsedRealtimeNanos) 311 .setAngleOfArrivalMeasurement(aoaMeasurement) 312 .setLineOfSight(TEST_LOS); 313 314 if (rangingMeasurementType == RANGING_MEASUREMENT_TYPE_TWO_WAY) { 315 rangingMeasurementBuilder 316 .setDistanceMeasurement( 317 new DistanceMeasurement.Builder() 318 .setMeters(TEST_DISTANCE / (double) 100) 319 .setErrorMeters(0) 320 .setConfidenceLevel(1.0) 321 .build()) 322 .setDestinationAngleOfArrivalMeasurement(aoaDestMeasurement) 323 .setRssiDbm(-TEST_RSSI / 2) 324 .setRangingMeasurementMetadata(rangingMeasurementMetadata); 325 } 326 327 if (rangingMeasurementType == RANGING_MEASUREMENT_TYPE_DL_TDOA) { 328 DlTDoAMeasurement dlTDoAMeasurement = new DlTDoAMeasurement.Builder() 329 .setMessageType(TEST_MESSAGE_TYPE) 330 .setMessageControl(TEST_MESSAGE_CONTROL) 331 .setBlockIndex(TEST_BLOCK_INDEX) 332 .setNLoS(TEST_LOS) 333 .setTxTimestamp(TEST_TIMESTAMP) 334 .setRxTimestamp(TEST_TIMESTAMP) 335 .setAnchorCfo(TEST_ANCHOR_CFO) 336 .setCfo(TEST_CFO) 337 .setInitiatorReplyTime(TEST_INTIATOR_REPLY_TIME) 338 .setResponderReplyTime(TEST_RESPONDER_REPLY_TIME) 339 .setInitiatorResponderTof(TEST_INITIATOR_RESPONDER_TOF) 340 .setAnchorLocation(TEST_ANCHOR_LOCATION) 341 .setActiveRangingRounds(TEST_ACTIVE_RANGING_ROUNDS) 342 .setRoundIndex(TEST_ROUND_INDEX) 343 .build(); 344 rangingMeasurementBuilder.setRssiDbm(-TEST_RSSI / 2); 345 rangingMeasurementBuilder.setRangingMeasurementMetadata(dlTDoAMeasurement.toBundle()); 346 } 347 348 return new RangingReport.Builder() 349 .addMeasurement(rangingMeasurementBuilder.build()) 350 .addRangingReportMetadata(rangingReportMetadata) 351 .build(); 352 } 353 354 /** Build UwbRadarData for all Radar Data Type(s). */ generateUwbRadarData(int radarDataType, int rangingStatus)355 public static UwbRadarData generateUwbRadarData(int radarDataType, int rangingStatus) { 356 switch (radarDataType) { 357 case RADAR_DATA_TYPE_RADAR_SWEEP_SAMPLES: 358 return generateRadarSweepSamplesUwbRadarData(rangingStatus); 359 default: 360 return generateDefaultUwbRadarData(); 361 } 362 } 363 364 /** Build UwbRadarData for Radar Sweep Samples Radar Data Type. */ generateRadarSweepSamplesUwbRadarData(int rangingStatus)365 public static UwbRadarData generateRadarSweepSamplesUwbRadarData(int rangingStatus) { 366 final int noOfRadarSweeps = 2; 367 final UwbRadarSweepData[] uwbRadarSweepData = new UwbRadarSweepData[noOfRadarSweeps]; 368 uwbRadarSweepData[0] = 369 new UwbRadarSweepData( 370 TEST_SEQ_COUNTER, 371 TEST_TIMESTAMP, 372 TEST_VENDOR_SPECIFIC_DATA, 373 TEST_SAMPLE_DATA); 374 uwbRadarSweepData[1] = 375 new UwbRadarSweepData( 376 TEST_SEQ_COUNTER2, 377 TEST_TIMESTAMP2, 378 TEST_VENDOR_SPECIFIC_DATA, 379 TEST_SAMPLE_DATA); 380 return new UwbRadarData( 381 TEST_SESSION_ID, 382 rangingStatus, 383 RADAR_DATA_TYPE_RADAR_SWEEP_SAMPLES, 384 TEST_SAMPLES_PER_SWEEP, 385 TEST_BITS_PER_SAMPLE, 386 TEST_SWEEP_OFFSET, 387 uwbRadarSweepData); 388 } 389 390 /* Create a UwbRadarData with no measurements */ generateDefaultUwbRadarData()391 private static UwbRadarData generateDefaultUwbRadarData() { 392 final int noOfRadarSweeps = 0; 393 final UwbRadarSweepData[] uwbEmptyRadarSweepData = new UwbRadarSweepData[noOfRadarSweeps]; 394 return new UwbRadarData( 395 TEST_SESSION_ID, 396 TEST_STATUS, 397 RADAR_DATA_TYPE_RADAR_SWEEP_SAMPLES, 398 TEST_SAMPLES_PER_SWEEP, 399 TEST_BITS_PER_SAMPLE, 400 TEST_SWEEP_OFFSET, 401 uwbEmptyRadarSweepData); 402 } 403 404 /** Build RadarData for all Radar Data Type(s). */ generateRadarData(UwbRadarData uwbRadarData)405 public static RadarData generateRadarData(UwbRadarData uwbRadarData) { 406 RadarData.Builder radarDataBuilder = 407 new RadarData.Builder() 408 .setStatusCode(uwbRadarData.statusCode) 409 .setRadarDataType(uwbRadarData.radarDataType) 410 .setSamplesPerSweep(uwbRadarData.samplesPerSweep) 411 .setBitsPerSample(uwbRadarData.bitsPerSample) 412 .setSweepOffset(uwbRadarData.sweepOffset); 413 if (uwbRadarData.radarDataType == RadarParams.RADAR_DATA_TYPE_RADAR_SWEEP_SAMPLES) { 414 for (UwbRadarSweepData sweepData : uwbRadarData.radarSweepData) { 415 radarDataBuilder.addSweepData( 416 new RadarSweepData.Builder() 417 .setSequenceNumber(sweepData.sequenceNumber) 418 .setTimestamp(sweepData.timestamp) 419 .setVendorSpecificData(sweepData.vendorSpecificData) 420 .setSampleData(sweepData.sampleData) 421 .build()); 422 } 423 } 424 return radarDataBuilder.build(); 425 } 426 427 /** 428 * Helper method to generate a {@link UwbRadarData} instance and a corresponding 429 * {@link RadarData}. 430 */ generateUwbRadarDataAndRadarData( int radarDataType)431 public static Pair<UwbRadarData, RadarData> generateUwbRadarDataAndRadarData( 432 int radarDataType) { 433 UwbRadarData uwbRadarData = generateUwbRadarData(radarDataType, TEST_STATUS); 434 RadarData radarData = generateRadarData(uwbRadarData); 435 return Pair.create(uwbRadarData, radarData); 436 } 437 } 438