• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 android.os.PersistableBundle;
27 import android.util.Pair;
28 import android.uwb.AngleMeasurement;
29 import android.uwb.AngleOfArrivalMeasurement;
30 import android.uwb.DistanceMeasurement;
31 import android.uwb.RangingMeasurement;
32 import android.uwb.RangingReport;
33 import android.uwb.UwbAddress;
34 
35 import com.android.modules.utils.build.SdkLevel;
36 import com.android.server.uwb.data.UwbDlTDoAMeasurement;
37 import com.android.server.uwb.data.UwbOwrAoaMeasurement;
38 import com.android.server.uwb.data.UwbRangingData;
39 import com.android.server.uwb.data.UwbTwoWayMeasurement;
40 import com.android.server.uwb.params.TlvUtil;
41 
42 import com.google.uwb.support.dltdoa.DlTDoAMeasurement;
43 import com.google.uwb.support.fira.FiraParams;
44 import com.google.uwb.support.oemextension.RangingReportMetadata;
45 
46 public class UwbTestUtils {
47     public static final int TEST_SESSION_ID = 7;
48     public static final int TEST_SESSION_ID_2 = 8;
49     public static final byte TEST_SESSION_TYPE = FiraParams.SESSION_TYPE_RANGING;
50     public static final byte[] PEER_SHORT_MAC_ADDRESS = {0x35, 0x37};
51     public static final long PEER_SHORT_MAC_ADDRESS_LONG = 0x3735L;
52     public static final byte[] PEER_EXTENDED_SHORT_MAC_ADDRESS =
53             {0x35, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
54     public static final long PEER_EXTENDED_SHORT_MAC_ADDRESS_LONG = 0x3735L;
55     public static final byte[] PEER_EXTENDED_MAC_ADDRESS =
56             {0x12, 0x14, 0x16, 0x18, 0x31, 0x33, 0x35, 0x37};
57     public static final long PEER_EXTENDED_MAC_ADDRESS_LONG = 0x3735333118161412L;
58     public static final byte[] PEER_EXTENDED_MAC_ADDRESS_2 =
59             {0x2, 0x4, 0x6, 0x8, 0x1, 0x3, 0x5, 0x7};
60     public static final long  PEER_EXTENDED_MAC_ADDRESS_2_LONG = 0x0705030108060402L;
61     public static final byte[] PEER_BAD_MAC_ADDRESS = {0x12, 0x14, 0x16, 0x18};
62     public static final UwbAddress PEER_EXTENDED_UWB_ADDRESS = UwbAddress.fromBytes(
63             PEER_EXTENDED_MAC_ADDRESS);
64     public static final UwbAddress PEER_EXTENDED_UWB_ADDRESS_2 = UwbAddress.fromBytes(
65             PEER_EXTENDED_MAC_ADDRESS_2);
66     public static final UwbAddress PEER_SHORT_UWB_ADDRESS = UwbAddress.fromBytes(
67             PEER_SHORT_MAC_ADDRESS);
68     public static final UwbAddress PEER_EXTENDED_SHORT_UWB_ADDRESS = UwbAddress.fromBytes(
69             PEER_EXTENDED_SHORT_MAC_ADDRESS);
70 
71     public static final PersistableBundle PERSISTABLE_BUNDLE = new PersistableBundle();
72     public static final byte[] DATA_PAYLOAD = new byte[] {0x13, 0x15, 0x18};
73     public static final int RANGING_MEASUREMENT_TYPE_UNDEFINED = 0; // RFU in spec
74     public static final int MAX_DATA_SIZE = 100;
75 
76     private static final byte[] TEST_RAW_NTF_DATA = {0x10, 0x01, 0x05};
77     private static final long TEST_SEQ_COUNTER = 5;
78     private static final int TEST_RCR_INDICATION = 7;
79     private static final long TEST_CURR_RANGING_INTERVAL = 100;
80     private static final int TEST_RANGING_MEASURES_TYPE = RANGING_MEASUREMENT_TYPE_TWO_WAY;
81     private static final int TEST_MAC_ADDRESS_MODE = 1;
82     private static final int TEST_STATUS = FiraParams.STATUS_CODE_OK;
83     private static final int TEST_LOS = 0;
84     private static final int TEST_DISTANCE = 101;
85     private static final float TEST_AOA_AZIMUTH = 67;
86     private static final int TEST_AOA_AZIMUTH_FOM = 50;
87     private static final int TEST_BAD_AOA_AZIMUTH_FOM = 150;
88     private static final float TEST_AOA_ELEVATION = 37;
89     private static final int TEST_AOA_ELEVATION_FOM = 90;
90     private static final float TEST_AOA_DEST_AZIMUTH = 67;
91     private static final int TEST_AOA_DEST_AZIMUTH_FOM = 50;
92     private static final float TEST_AOA_DEST_ELEVATION = 37;
93     private static final int TEST_AOA_DEST_ELEVATION_FOM = 90;
94     private static final int TEST_FRAME_SEQUENCE_NUMBER = 1;
95     private static final int TEST_BLOCK_IDX = 100;
96     private static final int TEST_SLOT_IDX = 10;
97     private static final int TEST_MESSAGE_TYPE = 1;
98     private static final int TEST_MESSAGE_CONTROL = 1331;
99     private static final int TEST_BLOCK_INDEX = 5;
100     private static final int TEST_ROUND_INDEX = 1;
101     private static final long TEST_TIMESTAMP = 500_000L;
102     private static final float TEST_ANCHOR_CFO = 100.0f;
103     private static final float TEST_CFO = 200.50f;
104     private static final long TEST_INTIATOR_REPLY_TIME = 500_000L;
105     private static final long TEST_RESPONDER_REPLY_TIME = 300_000L;
106     private static final int TEST_INITIATOR_RESPONDER_TOF = 500;
107     private static final byte[] TEST_ANCHOR_LOCATION = {0x01, 0x02, 0x03, 0x04,
108             0x05, 0x06, 0x07, 0x08, 0x09, 0x10};
109     private static final byte[] TEST_ACTIVE_RANGING_ROUNDS = {0x02, 0x08};
110     private static final int TEST_RSSI = 150;
111 
UwbTestUtils()112     private UwbTestUtils() {}
113 
114     /** Build UwbRangingData for all Ranging Measurement Type(s). */
generateRangingData( int rangingMeasurementType, int macAddressingMode, int rangingStatus)115     public static UwbRangingData generateRangingData(
116             int rangingMeasurementType, int macAddressingMode, int rangingStatus) {
117         byte[] macAddress = (macAddressingMode == MAC_ADDRESSING_MODE_SHORT)
118                 ? PEER_SHORT_MAC_ADDRESS : PEER_EXTENDED_MAC_ADDRESS;
119         return generateRangingData(
120                 rangingMeasurementType, macAddressingMode, macAddress, rangingStatus);
121     }
122 
123     /** Build UwbRangingData for all Ranging Measurement Type(s). */
generateRangingData( int rangingMeasurementType, int macAddressingMode, byte[] macAddress, int rangingStatus)124     public static UwbRangingData generateRangingData(
125             int rangingMeasurementType, int macAddressingMode, byte[] macAddress,
126             int rangingStatus) {
127         switch (rangingMeasurementType) {
128             case RANGING_MEASUREMENT_TYPE_TWO_WAY:
129                 return generateTwoWayMeasurementRangingData(rangingStatus);
130             case RANGING_MEASUREMENT_TYPE_OWR_AOA:
131                 return generateOwrAoaMeasurementRangingData(
132                         macAddressingMode, macAddress, rangingStatus);
133             case RANGING_MEASUREMENT_TYPE_DL_TDOA:
134                 return generateDlTDoAMeasurementRangingData(macAddressingMode, rangingStatus);
135             default:
136                 return generateDefaultRangingData();
137         }
138     }
139 
generateTwoWayMeasurementRangingData(int rangingStatus)140     private static UwbRangingData generateTwoWayMeasurementRangingData(int rangingStatus) {
141         final int noOfRangingMeasures = 1;
142         final UwbTwoWayMeasurement[] uwbTwoWayMeasurements =
143                 new UwbTwoWayMeasurement[noOfRangingMeasures];
144         uwbTwoWayMeasurements[0] = new UwbTwoWayMeasurement(PEER_SHORT_MAC_ADDRESS, rangingStatus,
145                 TEST_LOS, TEST_DISTANCE, convertFloatToQFormat(TEST_AOA_AZIMUTH, 9, 7),
146                 TEST_AOA_AZIMUTH_FOM, convertFloatToQFormat(TEST_AOA_ELEVATION, 9, 7),
147                 TEST_AOA_ELEVATION_FOM, convertFloatToQFormat(TEST_AOA_DEST_AZIMUTH, 9, 7),
148                 TEST_AOA_DEST_AZIMUTH_FOM, convertFloatToQFormat(TEST_AOA_DEST_ELEVATION, 9, 7),
149                 TEST_AOA_DEST_ELEVATION_FOM, TEST_SLOT_IDX, TEST_RSSI);
150         return new UwbRangingData(TEST_SEQ_COUNTER, TEST_SESSION_ID,
151                 TEST_RCR_INDICATION, TEST_CURR_RANGING_INTERVAL, RANGING_MEASUREMENT_TYPE_TWO_WAY,
152                 TEST_MAC_ADDRESS_MODE, noOfRangingMeasures, uwbTwoWayMeasurements,
153                 TEST_RAW_NTF_DATA);
154     }
155 
generateOwrAoaMeasurementRangingData( int macAddressingMode, byte[] macAddress, int rangingStatus)156     private static UwbRangingData generateOwrAoaMeasurementRangingData(
157             int macAddressingMode, byte[] macAddress, int rangingStatus) {
158         final int noOfRangingMeasures = 1;
159         final UwbOwrAoaMeasurement uwbOwrAoaMeasurement  = new UwbOwrAoaMeasurement(
160                 macAddress, rangingStatus, TEST_LOS,
161                 TEST_FRAME_SEQUENCE_NUMBER, TEST_BLOCK_IDX,
162                 convertFloatToQFormat(TEST_AOA_AZIMUTH, 9, 7), TEST_AOA_AZIMUTH_FOM,
163                 convertFloatToQFormat(TEST_AOA_ELEVATION, 9, 7), TEST_AOA_ELEVATION_FOM);
164         return new UwbRangingData(TEST_SEQ_COUNTER, TEST_SESSION_ID,
165                 TEST_RCR_INDICATION, TEST_CURR_RANGING_INTERVAL, RANGING_MEASUREMENT_TYPE_OWR_AOA,
166                 macAddressingMode, noOfRangingMeasures, uwbOwrAoaMeasurement,
167                 TEST_RAW_NTF_DATA);
168     }
169 
170     /** Generate an OWR ranging data with a bad AoA Azimuth FOM */
generateBadOwrAoaMeasurementRangingData( int macAddressingMode, byte[] macAddress)171     public static UwbRangingData generateBadOwrAoaMeasurementRangingData(
172             int macAddressingMode, byte[] macAddress) {
173         final int noOfRangingMeasures = 1;
174         final UwbOwrAoaMeasurement uwbOwrAoaMeasurement  = new UwbOwrAoaMeasurement(
175                 macAddress, TEST_STATUS, TEST_LOS,
176                 TEST_FRAME_SEQUENCE_NUMBER, TEST_BLOCK_IDX,
177                 convertFloatToQFormat(TEST_AOA_AZIMUTH, 9, 7), TEST_BAD_AOA_AZIMUTH_FOM,
178                 convertFloatToQFormat(TEST_AOA_ELEVATION, 9, 7), TEST_AOA_ELEVATION_FOM);
179         return new UwbRangingData(TEST_SEQ_COUNTER, TEST_SESSION_ID,
180                 TEST_RCR_INDICATION, TEST_CURR_RANGING_INTERVAL, RANGING_MEASUREMENT_TYPE_OWR_AOA,
181                 macAddressingMode, noOfRangingMeasures, uwbOwrAoaMeasurement,
182                 TEST_RAW_NTF_DATA);
183     }
184 
generateDlTDoAMeasurementRangingData( int macAddressingMode, int rangingStatus)185     private static UwbRangingData generateDlTDoAMeasurementRangingData(
186             int macAddressingMode, int rangingStatus) {
187         final int noOfRangingMeasures = 1;
188         byte[] macAddress = (macAddressingMode == MAC_ADDRESSING_MODE_SHORT)
189                 ? PEER_SHORT_MAC_ADDRESS : PEER_EXTENDED_MAC_ADDRESS;
190         final UwbDlTDoAMeasurement[] uwbDlTDoAMeasurements =
191                 new UwbDlTDoAMeasurement[noOfRangingMeasures];
192         uwbDlTDoAMeasurements[0] = new UwbDlTDoAMeasurement(macAddress, rangingStatus,
193                 TEST_MESSAGE_TYPE, TEST_MESSAGE_CONTROL, TEST_BLOCK_INDEX, TEST_ROUND_INDEX,
194                 TEST_LOS, convertFloatToQFormat(TEST_AOA_AZIMUTH, 9, 7),
195                 TEST_AOA_AZIMUTH_FOM, convertFloatToQFormat(TEST_AOA_ELEVATION, 9, 7),
196                 TEST_AOA_ELEVATION_FOM, TEST_RSSI, TEST_TIMESTAMP, TEST_TIMESTAMP,
197                 convertFloatToQFormat(TEST_ANCHOR_CFO, 5, 11),
198                 convertFloatToQFormat(TEST_CFO, 5, 11), TEST_INTIATOR_REPLY_TIME,
199                 TEST_RESPONDER_REPLY_TIME, TEST_INITIATOR_RESPONDER_TOF, TEST_ANCHOR_LOCATION,
200                 TEST_ACTIVE_RANGING_ROUNDS);
201 
202         return new UwbRangingData(TEST_SEQ_COUNTER, TEST_SESSION_ID,
203                 TEST_RCR_INDICATION, TEST_CURR_RANGING_INTERVAL, RANGING_MEASUREMENT_TYPE_DL_TDOA,
204                 macAddressingMode, noOfRangingMeasures, uwbDlTDoAMeasurements,
205                 TEST_RAW_NTF_DATA);
206     }
207 
208     // Create a UwbRangingData with no measurements, for negative test cases (example: incorrect
209     // ranging measurement type).
generateDefaultRangingData()210     private static UwbRangingData generateDefaultRangingData() {
211         final int noOfRangingMeasures = 0;
212         final UwbTwoWayMeasurement[] uwbEmptyTwoWayMeasurements =
213                 new UwbTwoWayMeasurement[noOfRangingMeasures];
214         return new UwbRangingData(TEST_SEQ_COUNTER, TEST_SESSION_ID,
215                 TEST_RCR_INDICATION, TEST_CURR_RANGING_INTERVAL, RANGING_MEASUREMENT_TYPE_UNDEFINED,
216                 TEST_MAC_ADDRESS_MODE, noOfRangingMeasures, uwbEmptyTwoWayMeasurements,
217                 TEST_RAW_NTF_DATA);
218     }
219 
220     // 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)221     public static Pair<UwbRangingData, RangingReport> generateRangingDataAndRangingReport(
222             byte[] macAddress, int macAddressingMode, int rangingMeasurementType,
223             boolean isAoaAzimuthEnabled, boolean isAoaElevationEnabled,
224             boolean isDestAoaAzimuthEnabled, boolean isDestAoaElevationEnabled,
225             long elapsedRealtimeNanos) {
226         UwbRangingData uwbRangingData = generateRangingData(rangingMeasurementType,
227                 macAddressingMode, TEST_STATUS);
228 
229         PersistableBundle rangingReportMetadata = new RangingReportMetadata.Builder()
230                 .setSessionId(0)
231                 .setRawNtfData(new byte[] {0x10, 0x01, 0x05})
232                 .build()
233                 .toBundle();
234 
235         AngleOfArrivalMeasurement aoaMeasurement = null;
236         AngleOfArrivalMeasurement aoaDestMeasurement = null;
237         if (isAoaAzimuthEnabled || isAoaElevationEnabled) {
238             AngleMeasurement aoaAzimuth = null;
239             AngleMeasurement aoaElevation = null;
240             AngleOfArrivalMeasurement.Builder aoaBuilder = null;
241 
242             if (isAoaAzimuthEnabled) {
243                 aoaAzimuth = new AngleMeasurement(
244                         degreeToRadian(TEST_AOA_AZIMUTH), 0,
245                         TEST_AOA_AZIMUTH_FOM / (double) 100);
246                 aoaBuilder = new AngleOfArrivalMeasurement.Builder(aoaAzimuth);
247             }
248             if (isAoaElevationEnabled && aoaBuilder != null) {
249                 aoaElevation = new AngleMeasurement(
250                         degreeToRadian(TEST_AOA_ELEVATION), 0,
251                         TEST_AOA_ELEVATION_FOM / (double) 100);
252                 aoaBuilder.setAltitude(aoaElevation);
253             }
254 
255             aoaMeasurement = (aoaBuilder != null) ? aoaBuilder.build() : null;
256         }
257         if (isDestAoaAzimuthEnabled || isDestAoaElevationEnabled) {
258             AngleMeasurement aoaDestAzimuth = null;
259             AngleMeasurement aoaDestElevation = null;
260             AngleOfArrivalMeasurement.Builder aoaBuilder = null;
261 
262             if (isDestAoaAzimuthEnabled) {
263                 aoaDestAzimuth =
264                         new AngleMeasurement(
265                                 degreeToRadian(TEST_AOA_DEST_AZIMUTH), 0,
266                                 TEST_AOA_DEST_AZIMUTH_FOM / (double) 100);
267                 aoaBuilder = new AngleOfArrivalMeasurement.Builder(aoaDestAzimuth);
268             }
269             if (isDestAoaElevationEnabled && aoaBuilder != null) {
270                 aoaDestElevation =
271                         new AngleMeasurement(
272                                 degreeToRadian(TEST_AOA_DEST_ELEVATION), 0,
273                                 TEST_AOA_DEST_ELEVATION_FOM / (double) 100);
274                 aoaBuilder.setAltitude(aoaDestElevation);
275             }
276             aoaDestMeasurement = (aoaBuilder != null) ? aoaBuilder.build() : null;
277         }
278 
279         RangingReport rangingReport = buildRangingReport(macAddress, rangingMeasurementType,
280                 aoaMeasurement, aoaDestMeasurement, elapsedRealtimeNanos, rangingReportMetadata);
281         return Pair.create(uwbRangingData, rangingReport);
282     }
283 
getComputedMacAddress(byte[] address)284     private static UwbAddress getComputedMacAddress(byte[] address) {
285         if (!SdkLevel.isAtLeastU()) {
286             return UwbAddress.fromBytes(TlvUtil.getReverseBytes(address));
287         }
288         return UwbAddress.fromBytes(address);
289     }
290 
buildRangingReport(byte[] macAddress, int rangingMeasurementType, AngleOfArrivalMeasurement aoaMeasurement, AngleOfArrivalMeasurement aoaDestMeasurement, long elapsedRealtimeNanos, PersistableBundle rangingReportMetadata)291     private static RangingReport buildRangingReport(byte[] macAddress, int rangingMeasurementType,
292             AngleOfArrivalMeasurement aoaMeasurement, AngleOfArrivalMeasurement aoaDestMeasurement,
293             long elapsedRealtimeNanos, PersistableBundle rangingReportMetadata) {
294 
295         PersistableBundle rangingMeasurementMetadata = new PersistableBundle();
296 
297         RangingMeasurement.Builder rangingMeasurementBuilder = new RangingMeasurement.Builder()
298                 .setRemoteDeviceAddress(getComputedMacAddress(macAddress))
299                 .setStatus(TEST_STATUS)
300                 .setElapsedRealtimeNanos(elapsedRealtimeNanos)
301                 .setAngleOfArrivalMeasurement(aoaMeasurement)
302                 .setLineOfSight(TEST_LOS);
303 
304         if (rangingMeasurementType == RANGING_MEASUREMENT_TYPE_TWO_WAY) {
305             rangingMeasurementBuilder
306                     .setDistanceMeasurement(
307                             new DistanceMeasurement.Builder()
308                                     .setMeters(TEST_DISTANCE / (double) 100)
309                                     .setErrorMeters(0)
310                                     .setConfidenceLevel(0)
311                                     .build())
312                     .setDestinationAngleOfArrivalMeasurement(aoaDestMeasurement)
313                     .setRssiDbm(-TEST_RSSI / 2)
314                     .setRangingMeasurementMetadata(rangingMeasurementMetadata);
315         }
316 
317         if (rangingMeasurementType == RANGING_MEASUREMENT_TYPE_DL_TDOA) {
318             DlTDoAMeasurement dlTDoAMeasurement = new DlTDoAMeasurement.Builder()
319                     .setMessageType(TEST_MESSAGE_TYPE)
320                     .setMessageControl(TEST_MESSAGE_CONTROL)
321                     .setBlockIndex(TEST_BLOCK_INDEX)
322                     .setNLoS(TEST_LOS)
323                     .setTxTimestamp(TEST_TIMESTAMP)
324                     .setRxTimestamp(TEST_TIMESTAMP)
325                     .setAnchorCfo(TEST_ANCHOR_CFO)
326                     .setCfo(TEST_CFO)
327                     .setInitiatorReplyTime(TEST_INTIATOR_REPLY_TIME)
328                     .setResponderReplyTime(TEST_RESPONDER_REPLY_TIME)
329                     .setInitiatorResponderTof(TEST_INITIATOR_RESPONDER_TOF)
330                     .setAnchorLocation(TEST_ANCHOR_LOCATION)
331                     .setActiveRangingRounds(TEST_ACTIVE_RANGING_ROUNDS)
332                     .setRoundIndex(TEST_ROUND_INDEX)
333                     .build();
334             rangingMeasurementBuilder.setRangingMeasurementMetadata(dlTDoAMeasurement.toBundle());
335         }
336 
337         return new RangingReport.Builder()
338                 .addMeasurement(rangingMeasurementBuilder.build())
339                 .addRangingReportMetadata(rangingReportMetadata)
340                 .build();
341     }
342 }
343