1 /*
2  * Copyright (C) 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 androidx.core.uwb.backend.impl.internal;
18 
19 import static com.google.uwb.support.fira.FiraParams.RANGE_DATA_NTF_CONFIG_DISABLE;
20 import static com.google.uwb.support.fira.FiraParams.RANGE_DATA_NTF_CONFIG_ENABLE;
21 import static com.google.uwb.support.fira.FiraParams.RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_EDGE_TRIG;
22 import static com.google.uwb.support.fira.FiraParams.RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_LEVEL_TRIG;
23 
24 import android.util.ArrayMap;
25 
26 import androidx.annotation.IntDef;
27 
28 import com.google.common.collect.ImmutableList;
29 import com.google.uwb.support.fira.FiraParams;
30 
31 import java.util.Map;
32 
33 /** Definitions that are common for all classes. */
34 public final class Utils {
35 
36     public static final String TAG = "UwbBackend";
37 
38     /** Supported Ranging configurations. */
39     @IntDef({
40         CONFIG_UNICAST_DS_TWR,
41         CONFIG_MULTICAST_DS_TWR,
42         CONFIG_UNICAST_DS_TWR_NO_AOA,
43         CONFIG_PROVISIONED_UNICAST_DS_TWR,
44         CONFIG_PROVISIONED_MULTICAST_DS_TWR,
45         CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_AOA,
46         CONFIG_PROVISIONED_INDIVIDUAL_MULTICAST_DS_TWR,
47         CONFIG_MULTICAST_DS_TWR_NO_AOA,
48         CONFIG_DL_TDOA_DT_TAG,
49         CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_RESULT_REPORT_PHASE,
50         CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_RESULT_REPORT_PHASE_HPRF
51     })
52     public @interface UwbConfigId {}
53 
54     /**
55      * FiRa-defined unicast {@code STATIC STS DS-TWR} ranging, deferred mode, ranging interval 240
56      * ms.
57      *
58      * <p>Typical use case: device tracking tags.
59      */
60     public static final int CONFIG_UNICAST_DS_TWR = 1;
61 
62     public static final int CONFIG_MULTICAST_DS_TWR = 2;
63 
64     /** Same as {@code CONFIG_ID_1}, except Angle-of-arrival (AoA) data is not reported. */
65     public static final int CONFIG_UNICAST_DS_TWR_NO_AOA = 3;
66 
67     /** Same as {@code CONFIG_ID_1}, except P-STS security mode is enabled. */
68     public static final int CONFIG_PROVISIONED_UNICAST_DS_TWR = 4;
69 
70     /** Same as {@code CONFIG_ID_2}, except P-STS security mode is enabled. */
71     public static final int CONFIG_PROVISIONED_MULTICAST_DS_TWR = 5;
72 
73     /** Same as {@code CONFIG_ID_3}, except P-STS security mode is enabled. */
74     public static final int CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_AOA = 6;
75 
76     /** Same as {@code CONFIG_ID_2}, except P-STS individual controlee key mode is enabled. */
77     public static final int CONFIG_PROVISIONED_INDIVIDUAL_MULTICAST_DS_TWR = 7;
78 
79     /** Same as {@code CONFIG_ID_3}, except not unicast @Hide */
80     public static final int CONFIG_MULTICAST_DS_TWR_NO_AOA = 1000;
81 
82     /** FiRa- defined Downlink-TDoA for DT-Tag ranging */
83     public static final int CONFIG_DL_TDOA_DT_TAG = 1001;
84 
85     /**
86      * Same as {@code CONFIG_ID_4}, except result report phase is disabled, fast ranging interval 96
87      * ms, filtering disabled, @Hide
88      */
89     public static final int CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_RESULT_REPORT_PHASE = 1002;
90 
91     /** Same as {@code CONFIG_ID_1002}, except PRF mode is HPRF, @Hide */
92     public static final int CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_RESULT_REPORT_PHASE_HPRF = 1003;
93 
94     @IntDef({
95         INFREQUENT,
96         NORMAL,
97         FAST,
98     })
99     public @interface RangingUpdateRate {}
100 
101     /**
102      * Reports ranging data in hundreds of milliseconds (depending on the ranging interval setting
103      * of the config)
104      */
105     public static final int NORMAL = 1;
106 
107     /** Reports ranging data in a couple of seconds (default to 4 seconds). */
108     public static final int INFREQUENT = 2;
109 
110     /** Reports ranging data as fast as possible (depending on the device's capability). */
111     public static final int FAST = 3;
112 
113     /**
114      * FiRa-defined one-to-many {@code STATIC STS DS-TWR} ranging, deferred mode, ranging interval
115      * 200 ms
116      *
117      * <p>Typical use case: smart phone interacts with many smart devices.
118      */
119     public static final int VENDOR_ID_SIZE = 2;
120 
121     public static final int STATIC_STS_IV_SIZE = 6;
122     public static final int STATIC_STS_SESSION_KEY_INFO_SIZE = VENDOR_ID_SIZE + STATIC_STS_IV_SIZE;
123 
124     // A map that stores the ranging interval values. The key is config ID.
125     private static final Map<Integer, RangingTimingParams> CONFIG_RANGING_INTERVAL_MAP =
126             new ArrayMap<>();
127 
128     /** Sets the default {@link RangingTimingParams} for given config ID. */
setRangingTimingParams( @wbConfigId int configId, RangingTimingParams params)129     public static void setRangingTimingParams(
130             @UwbConfigId int configId, RangingTimingParams params) {
131         CONFIG_RANGING_INTERVAL_MAP.put(configId, params);
132     }
133 
134     /** Gets the default {@link RangingTimingParams} of given config ID. */
getRangingTimingParams(@wbConfigId int configId)135     public static RangingTimingParams getRangingTimingParams(@UwbConfigId int configId) {
136         return CONFIG_RANGING_INTERVAL_MAP.get(configId);
137     }
138 
139     @IntDef({
140         STATUS_OK,
141         STATUS_ERROR,
142         INVALID_API_CALL,
143         RANGING_ALREADY_STARTED,
144         MISSING_PERMISSION_UWB_RANGING,
145         UWB_SYSTEM_CALLBACK_FAILURE
146     })
147     public @interface UwbStatusCodes {}
148 
149     // IMPORTANT NOTE: The codes referenced in this file are used on both the client and service
150     // side, and must not be modified after launch. It is fine to add new codes, but previously
151     // existing codes must be left unmodified.
152 
153     // Common status codes that may be used by a variety of actions.
154 
155     /** The operation was successful. */
156     public static final int STATUS_OK = 0; // 0
157 
158     /** The operation failed, without any more information. */
159     public static final int STATUS_ERROR = 1; // 13
160 
161     /** The call is not valid. For example, get Complex Channel for the controlee. */
162     public static final int INVALID_API_CALL = 2;
163 
164     /** The ranging is already started, this is a duplicated request. */
165     public static final int RANGING_ALREADY_STARTED = 3;
166 
167     /** Can't start ranging because the UWB_RANGING permission is not granted. */
168     public static final int MISSING_PERMISSION_UWB_RANGING = 4;
169 
170     /** Supported Range Data Notification Config */
171     @androidx.annotation.IntDef(
172             value = {
173                     RANGE_DATA_NTF_DISABLE,
174                     RANGE_DATA_NTF_ENABLE,
175                     RANGE_DATA_NTF_ENABLE_PROXIMITY_LEVEL_TRIG,
176                     RANGE_DATA_NTF_ENABLE_PROXIMITY_EDGE_TRIG,
177             })
178     public @interface RangeDataNtfConfig {}
179 
180     public static final int RANGE_DATA_NTF_DISABLE = 0;
181     public static final int RANGE_DATA_NTF_ENABLE = 1;
182     public static final int RANGE_DATA_NTF_ENABLE_PROXIMITY_LEVEL_TRIG = 2;
183     public static final int RANGE_DATA_NTF_ENABLE_PROXIMITY_EDGE_TRIG = 3;
184 
185     public static final ImmutableList<Integer> SUPPORTED_NTF_CONFIG =
186             ImmutableList.of(0, 1, 2, 3);
187 
188     /** Convert Fira range data Ntf config to Utils range data ntf config.*/
convertFromFiraNtfConfig( @iraParams.RangeDataNtfConfig int rangeDataConfig)189     public static @Utils.RangeDataNtfConfig int convertFromFiraNtfConfig(
190             @FiraParams.RangeDataNtfConfig int rangeDataConfig) {
191         switch (rangeDataConfig) {
192             case RANGE_DATA_NTF_CONFIG_DISABLE:
193                 return RANGE_DATA_NTF_DISABLE;
194             case RANGE_DATA_NTF_CONFIG_ENABLE:
195                 return RANGE_DATA_NTF_ENABLE;
196             case RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_LEVEL_TRIG:
197                 return RANGE_DATA_NTF_ENABLE_PROXIMITY_LEVEL_TRIG;
198             case RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_EDGE_TRIG :
199                 return RANGE_DATA_NTF_ENABLE_PROXIMITY_EDGE_TRIG;
200             default:
201                 return RANGE_DATA_NTF_ENABLE;
202         }
203     }
204     /** Convert Utils range data Ntf config to Fira range data ntf config.*/
convertToFiraNtfConfig( @tils.RangeDataNtfConfig int rangeDataConfig)205     public static @FiraParams.RangeDataNtfConfig int convertToFiraNtfConfig(
206             @Utils.RangeDataNtfConfig int rangeDataConfig) {
207         switch (rangeDataConfig) {
208             case RANGE_DATA_NTF_DISABLE:
209                 return RANGE_DATA_NTF_CONFIG_DISABLE;
210             case RANGE_DATA_NTF_ENABLE:
211                 return RANGE_DATA_NTF_CONFIG_ENABLE;
212             case RANGE_DATA_NTF_ENABLE_PROXIMITY_LEVEL_TRIG:
213                 return RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_LEVEL_TRIG;
214             case RANGE_DATA_NTF_ENABLE_PROXIMITY_EDGE_TRIG :
215                 return RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_EDGE_TRIG;
216             default:
217                 return RANGE_DATA_NTF_CONFIG_ENABLE;
218         }
219     }
220 
221     @IntDef(
222             value = {
223                     DURATION_1_MS,
224                     DURATION_2_MS,
225             }
226     )
227     public @interface SlotDuration {}
228 
229     public static final int DURATION_1_MS = 1;
230     public static final int DURATION_2_MS = 2;
231 
232     /**
233      * Unusual failures happened in UWB system callback, such as stopping ranging or removing a
234      * known controlee failed.
235      */
236     public static final int UWB_SYSTEM_CALLBACK_FAILURE = 5;
237 
238     /** Failed to reconfigure an existing ranging session. */
239     public static final int UWB_RECONFIGURATION_FAILURE = 6;
240 
241     static {
setRangingTimingParams( CONFIG_UNICAST_DS_TWR, new RangingTimingParams( 240, 120, 600, 6, 2400, 0, true))242         setRangingTimingParams(
243                 CONFIG_UNICAST_DS_TWR,
244                 new RangingTimingParams(
245                         /* rangingIntervalNormal= */ 240,
246                         /* rangingIntervalFast= */ 120,
247                         /* rangingIntervalInfrequent= */ 600,
248                         /* slotPerRangingRound= */ 6,
249                         /* slotDurationRstu= */ 2400,
250                         /* initiationTimeMs= */ 0,
251                         /* hoppingEnabled= */ true));
252 
setRangingTimingParams( CONFIG_MULTICAST_DS_TWR, new RangingTimingParams( 200, 120, 600, 20, 2400, 0, true))253         setRangingTimingParams(
254                 CONFIG_MULTICAST_DS_TWR,
255                 new RangingTimingParams(
256                         /* rangingIntervalNormal= */ 200,
257                         /* rangingIntervalFast= */ 120,
258                         /* rangingIntervalInfrequent= */ 600,
259                         /* slotPerRangingRound= */ 20,
260                         /* slotDurationRstu= */ 2400,
261                         /* initiationTimeMs= */ 0,
262                         /* hoppingEnabled= */ true));
263 
setRangingTimingParams( CONFIG_UNICAST_DS_TWR_NO_AOA, new RangingTimingParams( 200, 120, 600, 20, 2400, 0, true))264         setRangingTimingParams(
265                 CONFIG_UNICAST_DS_TWR_NO_AOA,
266                 new RangingTimingParams(
267                         /* rangingIntervalNormal= */ 200,
268                         /* rangingIntervalFast= */ 120,
269                         /* rangingIntervalInfrequent= */600,
270                         /* slotPerRangingRound= */ 20,
271                         /* slotDurationRstu= */ 2400,
272                         /* initiationTimeMs= */ 0,
273                         /* hoppingEnabled= */ true));
274 
setRangingTimingParams( CONFIG_PROVISIONED_UNICAST_DS_TWR, new RangingTimingParams( 240, 120, 600, 6, 2400, 0, true))275         setRangingTimingParams(
276                 CONFIG_PROVISIONED_UNICAST_DS_TWR,
277                 new RangingTimingParams(
278                         /* rangingIntervalNormal= */ 240,
279                         /* rangingIntervalFast= */ 120,
280                         /* rangingIntervalInfrequent= */ 600,
281                         /* slotPerRangingRound= */ 6,
282                         /* slotDurationRstu= */ 2400,
283                         /* initiationTimeMs= */ 0,
284                         /* hoppingEnabled= */ true));
285 
setRangingTimingParams( CONFIG_PROVISIONED_MULTICAST_DS_TWR, new RangingTimingParams( 200, 120, 600, 20, 2400, 0, true))286         setRangingTimingParams(
287                 CONFIG_PROVISIONED_MULTICAST_DS_TWR,
288                 new RangingTimingParams(
289                         /* rangingIntervalNormal= */ 200,
290                         /* rangingIntervalFast= */ 120,
291                         /* rangingIntervalInfrequent= */ 600,
292                         /* slotPerRangingRound= */ 20,
293                         /* slotDurationRstu= */ 2400,
294                         /* initiationTimeMs= */ 0,
295                         /* hoppingEnabled= */ true));
296 
setRangingTimingParams( CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_AOA, new RangingTimingParams( 200, 120, 600, 20, 2400, 0, true))297         setRangingTimingParams(
298                 CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_AOA,
299                 new RangingTimingParams(
300                         /* rangingIntervalNormal= */ 200,
301                         /* rangingIntervalFast= */ 120,
302                         /* rangingIntervalInfrequent= */ 600,
303                         /* slotPerRangingRound= */ 20,
304                         /* slotDurationRstu= */ 2400,
305                         /* initiationTimeMs= */ 0,
306                         /* hoppingEnabled= */ true));
307 
setRangingTimingParams( CONFIG_PROVISIONED_INDIVIDUAL_MULTICAST_DS_TWR, new RangingTimingParams( 200, 120, 600, 20, 2400, 0, true))308         setRangingTimingParams(
309                 CONFIG_PROVISIONED_INDIVIDUAL_MULTICAST_DS_TWR,
310                 new RangingTimingParams(
311                         /* rangingIntervalNormal= */ 200,
312                         /* rangingIntervalFast= */ 120,
313                         /* rangingIntervalInfrequent= */ 600,
314                         /* slotPerRangingRound= */ 20,
315                         /* slotDurationRstu= */ 2400,
316                         /* initiationTimeMs= */ 0,
317                         /* hoppingEnabled= */ true));
318 
setRangingTimingParams( CONFIG_DL_TDOA_DT_TAG, new RangingTimingParams( 200, 120, 600, 20, 2400, 0, true))319         setRangingTimingParams(
320                 CONFIG_DL_TDOA_DT_TAG,
321                 new RangingTimingParams(
322                         /* rangingIntervalNormal= */ 200,
323                         /* rangingIntervalFast= */ 120,
324                         /* rangingIntervalInfrequent= */ 600,
325                         /* slotPerRangingRound= */ 20,
326                         /* slotDurationRstu= */ 2400,
327                         /* initiationTimeMs= */ 0,
328                         /* hoppingEnabled= */ true));
329 
setRangingTimingParams( CONFIG_MULTICAST_DS_TWR_NO_AOA, new RangingTimingParams( 200, 120, 600, 20, 2400, 0, true))330         setRangingTimingParams(
331                 CONFIG_MULTICAST_DS_TWR_NO_AOA,
332                 new RangingTimingParams(
333                         /* rangingIntervalNormal= */ 200,
334                         /* rangingIntervalFast= */ 120,
335                         /* rangingIntervalInfrequent= */ 600,
336                         /* slotPerRangingRound= */ 20,
337                         /* slotDurationRstu= */ 2400,
338                         /* initiationTimeMs= */ 0,
339                         /* hoppingEnabled= */ true));
340 
setRangingTimingParams( CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_RESULT_REPORT_PHASE, new RangingTimingParams( 240, 96, 600, 6, 2400, 0, true))341         setRangingTimingParams(
342                 CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_RESULT_REPORT_PHASE,
343                 new RangingTimingParams(
344                         /* rangingIntervalNormal= */ 240,
345                         /* rangingIntervalFast= */ 96,
346                         /* rangingIntervalInfrequent= */ 600,
347                         /* slotPerRangingRound= */ 6,
348                         /* slotDurationRstu= */ 2400,
349                         /* initiationTimeMs= */ 0,
350                         /* hoppingEnabled= */ true));
351 
setRangingTimingParams( CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_RESULT_REPORT_PHASE_HPRF, new RangingTimingParams( 240, 96, 600, 6, 2400, 0, true))352         setRangingTimingParams(
353                 CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_RESULT_REPORT_PHASE_HPRF,
354                 new RangingTimingParams(
355                         /* rangingIntervalNormal= */ 240,
356                         /* rangingIntervalFast= */ 96,
357                         /* rangingIntervalInfrequent= */ 600,
358                         /* slotPerRangingRound= */ 6,
359                         /* slotDurationRstu= */ 2400,
360                         /* initiationTimeMs= */ 0,
361                         /* hoppingEnabled= */ true));
362     }
363 
364     public static int channelForTesting = 9;
365     public static int preambleIndexForTesting = 11;
366 
367     // Channels defined in FiRa Spec
368     public static final ImmutableList<Integer> SUPPORTED_CHANNELS =
369             ImmutableList.of(5, 6, 8, 9, 10, 12, 13, 14);
370 
371     // Preamble index used by BPRF (base pulse repetition frequency) mode. BPRF supports bitrate up
372     // to 6Mb/s, which is good enough for ranging purpose.
373     public static final ImmutableList<Integer> SUPPORTED_BPRF_PREAMBLE_INDEX =
374             ImmutableList.of(9, 10, 11, 12);
375 
376     // Preamble index used by HPRF (high pulse repetition frequency) mode. HPRF supports bitrate up
377     // to 31.2 Mbps.
378     public static final ImmutableList<Integer> SUPPORTED_HPRF_PREAMBLE_INDEX =
379             ImmutableList.of(25, 26, 27, 28, 19, 30, 31, 32);
380 
381     /** Converts millisecond to RSTU. */
convertMsToRstu(int value)382     public static int convertMsToRstu(int value) {
383         return (int) (value * 499.2 * 1000 / 416);
384     }
385 
Utils()386     private Utils() {}
387 }
388