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 androidx.core.uwb.backend.impl.internal.Utils.CONFIG_DL_TDOA_DT_TAG; 20 import static androidx.core.uwb.backend.impl.internal.Utils.CONFIG_MULTICAST_DS_TWR; 21 import static androidx.core.uwb.backend.impl.internal.Utils.CONFIG_MULTICAST_DS_TWR_NO_AOA; 22 import static androidx.core.uwb.backend.impl.internal.Utils.CONFIG_PROVISIONED_INDIVIDUAL_MULTICAST_DS_TWR; 23 import static androidx.core.uwb.backend.impl.internal.Utils.CONFIG_PROVISIONED_MULTICAST_DS_TWR; 24 import static androidx.core.uwb.backend.impl.internal.Utils.CONFIG_PROVISIONED_UNICAST_DS_TWR; 25 import static androidx.core.uwb.backend.impl.internal.Utils.CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_AOA; 26 import static androidx.core.uwb.backend.impl.internal.Utils.CONFIG_UNICAST_DS_TWR; 27 import static androidx.core.uwb.backend.impl.internal.Utils.CONFIG_UNICAST_DS_TWR_NO_AOA; 28 import static androidx.core.uwb.backend.impl.internal.Utils.CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_RESULT_REPORT_PHASE; 29 import static androidx.core.uwb.backend.impl.internal.Utils.CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_RESULT_REPORT_PHASE_HPRF; 30 import static androidx.core.uwb.backend.impl.internal.Utils.STATIC_STS_SESSION_KEY_INFO_SIZE; 31 import static androidx.core.uwb.backend.impl.internal.Utils.VENDOR_ID_SIZE; 32 import static androidx.core.uwb.backend.impl.internal.Utils.getRangingTimingParams; 33 34 import static com.google.uwb.support.fira.FiraParams.AOA_RESULT_REQUEST_MODE_NO_AOA_REPORT; 35 import static com.google.uwb.support.fira.FiraParams.FILTER_TYPE_NONE; 36 import static com.google.uwb.support.fira.FiraParams.HOPPING_MODE_FIRA_HOPPING_ENABLE; 37 import static com.google.uwb.support.fira.FiraParams.MAC_ADDRESS_MODE_2_BYTES; 38 import static com.google.uwb.support.fira.FiraParams.MULTI_NODE_MODE_ONE_TO_MANY; 39 import static com.google.uwb.support.fira.FiraParams.MULTI_NODE_MODE_UNICAST; 40 import static com.google.uwb.support.fira.FiraParams.PRF_MODE_HPRF; 41 import static com.google.uwb.support.fira.FiraParams.PROTOCOL_VERSION_1_1; 42 import static com.google.uwb.support.fira.FiraParams.RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_EDGE_TRIG; 43 import static com.google.uwb.support.fira.FiraParams.RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_LEVEL_TRIG; 44 import static com.google.uwb.support.fira.FiraParams.RANGING_DEVICE_DT_TAG; 45 import static com.google.uwb.support.fira.FiraParams.RANGING_DEVICE_ROLE_INITIATOR; 46 import static com.google.uwb.support.fira.FiraParams.RANGING_DEVICE_ROLE_RESPONDER; 47 import static com.google.uwb.support.fira.FiraParams.RANGING_DEVICE_TYPE_CONTROLEE; 48 import static com.google.uwb.support.fira.FiraParams.RANGING_DEVICE_TYPE_CONTROLLER; 49 import static com.google.uwb.support.fira.FiraParams.RANGING_DEVICE_TYPE_DT_TAG; 50 import static com.google.uwb.support.fira.FiraParams.RANGING_ROUND_USAGE_DL_TDOA; 51 import static com.google.uwb.support.fira.FiraParams.RANGING_ROUND_USAGE_DS_TWR_DEFERRED_MODE; 52 import static com.google.uwb.support.fira.FiraParams.RFRAME_CONFIG_SP1; 53 import static com.google.uwb.support.fira.FiraParams.STS_CONFIG_PROVISIONED; 54 import static com.google.uwb.support.fira.FiraParams.STS_CONFIG_PROVISIONED_FOR_CONTROLEE_INDIVIDUAL_KEY; 55 56 import android.util.ArrayMap; 57 58 import androidx.annotation.Nullable; 59 60 import com.google.uwb.support.fira.FiraControleeParams; 61 import com.google.uwb.support.fira.FiraOpenSessionParams; 62 import com.google.uwb.support.fira.FiraParams; 63 import com.google.uwb.support.fira.FiraRangingReconfigureParams; 64 65 import java.util.Arrays; 66 import java.util.Map; 67 68 /** 69 * Creates the session-opening bundles for a FiRa session. The default parameters are 70 * profile-dependent. 71 */ 72 public final class ConfigurationManager { 73 74 private static final Map<Integer, UwbConfiguration> sConfigs = new ArrayMap<>(); 75 76 static { 77 // ID_1 properties. sConfigs.put( CONFIG_UNICAST_DS_TWR, new UwbConfiguration() { @Override public int getConfigId() { return CONFIG_UNICAST_DS_TWR; } @Override public int getMultiNodeMode() { return MULTI_NODE_MODE_UNICAST; } @Override public int getStsConfig() { return FiraParams.STS_CONFIG_STATIC; } @Override public int getAoaResultRequestMode() { return FiraParams.AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS; } @Override public boolean isControllerTheInitiator() { return true; } @Override public int getRangingRoundUsage() { return RANGING_ROUND_USAGE_DS_TWR_DEFERRED_MODE; } })78 sConfigs.put( 79 CONFIG_UNICAST_DS_TWR, 80 new UwbConfiguration() { 81 82 @Override 83 public int getConfigId() { 84 return CONFIG_UNICAST_DS_TWR; 85 } 86 87 @Override 88 public int getMultiNodeMode() { 89 return MULTI_NODE_MODE_UNICAST; 90 } 91 92 @Override 93 public int getStsConfig() { 94 return FiraParams.STS_CONFIG_STATIC; 95 } 96 97 @Override 98 public int getAoaResultRequestMode() { 99 return FiraParams.AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS; 100 } 101 102 @Override 103 public boolean isControllerTheInitiator() { 104 return true; 105 } 106 107 @Override 108 public int getRangingRoundUsage() { 109 return RANGING_ROUND_USAGE_DS_TWR_DEFERRED_MODE; 110 } 111 }); 112 113 // ID_2 properties. sConfigs.put( CONFIG_MULTICAST_DS_TWR, new UwbConfiguration() { @Override public int getConfigId() { return CONFIG_MULTICAST_DS_TWR; } @Override public int getMultiNodeMode() { return MULTI_NODE_MODE_ONE_TO_MANY; } @Override public int getStsConfig() { return FiraParams.STS_CONFIG_STATIC; } @Override public int getAoaResultRequestMode() { return FiraParams.AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS; } @Override public boolean isControllerTheInitiator() { return true; } @Override public int getRangingRoundUsage() { return RANGING_ROUND_USAGE_DS_TWR_DEFERRED_MODE; } })114 sConfigs.put( 115 CONFIG_MULTICAST_DS_TWR, 116 new UwbConfiguration() { 117 118 @Override 119 public int getConfigId() { 120 return CONFIG_MULTICAST_DS_TWR; 121 } 122 123 @Override 124 public int getMultiNodeMode() { 125 return MULTI_NODE_MODE_ONE_TO_MANY; 126 } 127 128 @Override 129 public int getStsConfig() { 130 return FiraParams.STS_CONFIG_STATIC; 131 } 132 133 @Override 134 public int getAoaResultRequestMode() { 135 return FiraParams.AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS; 136 } 137 138 @Override 139 public boolean isControllerTheInitiator() { 140 return true; 141 } 142 143 @Override 144 public int getRangingRoundUsage() { 145 return RANGING_ROUND_USAGE_DS_TWR_DEFERRED_MODE; 146 } 147 }); 148 149 // ID_3 properties. sConfigs.put( CONFIG_UNICAST_DS_TWR_NO_AOA, new UwbConfiguration() { @Override public int getConfigId() { return CONFIG_UNICAST_DS_TWR_NO_AOA; } @Override public int getMultiNodeMode() { return MULTI_NODE_MODE_UNICAST; } @Override public int getStsConfig() { return FiraParams.STS_CONFIG_STATIC; } @Override public int getAoaResultRequestMode() { return AOA_RESULT_REQUEST_MODE_NO_AOA_REPORT; } @Override public boolean isControllerTheInitiator() { return true; } @Override public int getRangingRoundUsage() { return RANGING_ROUND_USAGE_DS_TWR_DEFERRED_MODE; } })150 sConfigs.put( 151 CONFIG_UNICAST_DS_TWR_NO_AOA, 152 new UwbConfiguration() { 153 154 @Override 155 public int getConfigId() { 156 return CONFIG_UNICAST_DS_TWR_NO_AOA; 157 } 158 159 @Override 160 public int getMultiNodeMode() { 161 return MULTI_NODE_MODE_UNICAST; 162 } 163 164 @Override 165 public int getStsConfig() { 166 return FiraParams.STS_CONFIG_STATIC; 167 } 168 169 @Override 170 public int getAoaResultRequestMode() { 171 return AOA_RESULT_REQUEST_MODE_NO_AOA_REPORT; 172 } 173 174 @Override 175 public boolean isControllerTheInitiator() { 176 return true; 177 } 178 179 @Override 180 public int getRangingRoundUsage() { 181 return RANGING_ROUND_USAGE_DS_TWR_DEFERRED_MODE; 182 } 183 }); 184 185 // ID_4 properties. sConfigs.put( CONFIG_PROVISIONED_UNICAST_DS_TWR, new UwbConfiguration() { @Override public int getConfigId() { return CONFIG_PROVISIONED_UNICAST_DS_TWR; } @Override public int getMultiNodeMode() { return MULTI_NODE_MODE_UNICAST; } @Override public int getStsConfig() { return STS_CONFIG_PROVISIONED; } @Override public int getAoaResultRequestMode() { return FiraParams.AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS; } @Override public boolean isControllerTheInitiator() { return true; } @Override public int getRangingRoundUsage() { return RANGING_ROUND_USAGE_DS_TWR_DEFERRED_MODE; } })186 sConfigs.put( 187 CONFIG_PROVISIONED_UNICAST_DS_TWR, 188 new UwbConfiguration() { 189 190 @Override 191 public int getConfigId() { 192 return CONFIG_PROVISIONED_UNICAST_DS_TWR; 193 } 194 195 @Override 196 public int getMultiNodeMode() { 197 return MULTI_NODE_MODE_UNICAST; 198 } 199 200 @Override 201 public int getStsConfig() { 202 return STS_CONFIG_PROVISIONED; 203 } 204 205 @Override 206 public int getAoaResultRequestMode() { 207 return FiraParams.AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS; 208 } 209 210 @Override 211 public boolean isControllerTheInitiator() { 212 return true; 213 } 214 215 @Override 216 public int getRangingRoundUsage() { 217 return RANGING_ROUND_USAGE_DS_TWR_DEFERRED_MODE; 218 } 219 }); 220 221 // ID_5 properties. sConfigs.put( CONFIG_PROVISIONED_MULTICAST_DS_TWR, new UwbConfiguration() { @Override public int getConfigId() { return CONFIG_PROVISIONED_MULTICAST_DS_TWR; } @Override public int getMultiNodeMode() { return MULTI_NODE_MODE_ONE_TO_MANY; } @Override public int getStsConfig() { return STS_CONFIG_PROVISIONED; } @Override public int getAoaResultRequestMode() { return FiraParams.AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS; } @Override public boolean isControllerTheInitiator() { return true; } @Override public int getRangingRoundUsage() { return RANGING_ROUND_USAGE_DS_TWR_DEFERRED_MODE; } })222 sConfigs.put( 223 CONFIG_PROVISIONED_MULTICAST_DS_TWR, 224 new UwbConfiguration() { 225 226 @Override 227 public int getConfigId() { 228 return CONFIG_PROVISIONED_MULTICAST_DS_TWR; 229 } 230 231 @Override 232 public int getMultiNodeMode() { 233 return MULTI_NODE_MODE_ONE_TO_MANY; 234 } 235 236 @Override 237 public int getStsConfig() { 238 return STS_CONFIG_PROVISIONED; 239 } 240 241 @Override 242 public int getAoaResultRequestMode() { 243 return FiraParams.AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS; 244 } 245 246 @Override 247 public boolean isControllerTheInitiator() { 248 return true; 249 } 250 251 @Override 252 public int getRangingRoundUsage() { 253 return RANGING_ROUND_USAGE_DS_TWR_DEFERRED_MODE; 254 } 255 }); 256 257 // ID_6 properties. sConfigs.put( CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_AOA, new UwbConfiguration() { @Override public int getConfigId() { return CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_AOA; } @Override public int getMultiNodeMode() { return MULTI_NODE_MODE_UNICAST; } @Override public int getStsConfig() { return STS_CONFIG_PROVISIONED; } @Override public int getAoaResultRequestMode() { return AOA_RESULT_REQUEST_MODE_NO_AOA_REPORT; } @Override public boolean isControllerTheInitiator() { return true; } @Override public int getRangingRoundUsage() { return RANGING_ROUND_USAGE_DS_TWR_DEFERRED_MODE; } })258 sConfigs.put( 259 CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_AOA, 260 new UwbConfiguration() { 261 @Override 262 public int getConfigId() { 263 return CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_AOA; 264 } 265 266 @Override 267 public int getMultiNodeMode() { 268 return MULTI_NODE_MODE_UNICAST; 269 } 270 271 @Override 272 public int getStsConfig() { 273 return STS_CONFIG_PROVISIONED; 274 } 275 276 @Override 277 public int getAoaResultRequestMode() { 278 return AOA_RESULT_REQUEST_MODE_NO_AOA_REPORT; 279 } 280 281 @Override 282 public boolean isControllerTheInitiator() { 283 return true; 284 } 285 286 @Override 287 public int getRangingRoundUsage() { 288 return RANGING_ROUND_USAGE_DS_TWR_DEFERRED_MODE; 289 } 290 }); 291 292 // ID_7 properties. sConfigs.put( CONFIG_PROVISIONED_INDIVIDUAL_MULTICAST_DS_TWR, new UwbConfiguration() { @Override public int getConfigId() { return CONFIG_PROVISIONED_INDIVIDUAL_MULTICAST_DS_TWR; } @Override public int getMultiNodeMode() { return MULTI_NODE_MODE_ONE_TO_MANY; } @Override public int getStsConfig() { return FiraParams.STS_CONFIG_PROVISIONED_FOR_CONTROLEE_INDIVIDUAL_KEY; } @Override public int getAoaResultRequestMode() { return FiraParams.AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS; } @Override public boolean isControllerTheInitiator() { return true; } @Override public int getRangingRoundUsage() { return RANGING_ROUND_USAGE_DS_TWR_DEFERRED_MODE; } })293 sConfigs.put( 294 CONFIG_PROVISIONED_INDIVIDUAL_MULTICAST_DS_TWR, 295 new UwbConfiguration() { 296 297 @Override 298 public int getConfigId() { 299 return CONFIG_PROVISIONED_INDIVIDUAL_MULTICAST_DS_TWR; 300 } 301 302 @Override 303 public int getMultiNodeMode() { 304 return MULTI_NODE_MODE_ONE_TO_MANY; 305 } 306 307 @Override 308 public int getStsConfig() { 309 return FiraParams.STS_CONFIG_PROVISIONED_FOR_CONTROLEE_INDIVIDUAL_KEY; 310 } 311 312 @Override 313 public int getAoaResultRequestMode() { 314 return FiraParams.AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS; 315 } 316 317 @Override 318 public boolean isControllerTheInitiator() { 319 return true; 320 } 321 322 @Override 323 public int getRangingRoundUsage() { 324 return RANGING_ROUND_USAGE_DS_TWR_DEFERRED_MODE; 325 } 326 }); 327 328 // ID_1001 properties. sConfigs.put( CONFIG_DL_TDOA_DT_TAG, new UwbConfiguration() { @Override public int getConfigId() { return CONFIG_DL_TDOA_DT_TAG; } @Override public int getMultiNodeMode() { return MULTI_NODE_MODE_ONE_TO_MANY; } @Override public int getStsConfig() { return FiraParams.STS_CONFIG_STATIC; } @Override public int getAoaResultRequestMode() { return FiraParams.AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS; } @Override public boolean isControllerTheInitiator() { return true; } @Override public int getRangingRoundUsage() { return RANGING_ROUND_USAGE_DL_TDOA; } })329 sConfigs.put( 330 CONFIG_DL_TDOA_DT_TAG, 331 new UwbConfiguration() { 332 333 @Override 334 public int getConfigId() { 335 return CONFIG_DL_TDOA_DT_TAG; 336 } 337 338 @Override 339 public int getMultiNodeMode() { 340 return MULTI_NODE_MODE_ONE_TO_MANY; 341 } 342 343 @Override 344 public int getStsConfig() { 345 return FiraParams.STS_CONFIG_STATIC; 346 } 347 348 @Override 349 public int getAoaResultRequestMode() { 350 return FiraParams.AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS; 351 } 352 353 @Override 354 public boolean isControllerTheInitiator() { 355 return true; 356 } 357 358 @Override 359 public int getRangingRoundUsage() { 360 return RANGING_ROUND_USAGE_DL_TDOA; 361 } 362 }); 363 364 // ID_1000 properties. sConfigs.put( CONFIG_MULTICAST_DS_TWR_NO_AOA, new UwbConfiguration() { @Override public int getConfigId() { return CONFIG_UNICAST_DS_TWR_NO_AOA; } @Override public int getMultiNodeMode() { return MULTI_NODE_MODE_ONE_TO_MANY; } @Override public int getStsConfig() { return FiraParams.STS_CONFIG_STATIC; } @Override public int getAoaResultRequestMode() { return AOA_RESULT_REQUEST_MODE_NO_AOA_REPORT; } @Override public boolean isControllerTheInitiator() { return true; } @Override public int getRangingRoundUsage() { return RANGING_ROUND_USAGE_DS_TWR_DEFERRED_MODE; } })365 sConfigs.put( 366 CONFIG_MULTICAST_DS_TWR_NO_AOA, 367 new UwbConfiguration() { 368 369 @Override 370 public int getConfigId() { 371 return CONFIG_UNICAST_DS_TWR_NO_AOA; 372 } 373 374 @Override 375 public int getMultiNodeMode() { 376 return MULTI_NODE_MODE_ONE_TO_MANY; 377 } 378 379 @Override 380 public int getStsConfig() { 381 return FiraParams.STS_CONFIG_STATIC; 382 } 383 384 @Override 385 public int getAoaResultRequestMode() { 386 return AOA_RESULT_REQUEST_MODE_NO_AOA_REPORT; 387 } 388 389 @Override 390 public boolean isControllerTheInitiator() { 391 return true; 392 } 393 394 @Override 395 public int getRangingRoundUsage() { 396 return RANGING_ROUND_USAGE_DS_TWR_DEFERRED_MODE; 397 } 398 }); 399 400 // ID_1002 properties. sConfigs.put( CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_RESULT_REPORT_PHASE, new UwbConfiguration() { @Override public int getConfigId() { return CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_RESULT_REPORT_PHASE; } @Override public int getMultiNodeMode() { return MULTI_NODE_MODE_UNICAST; } @Override public int getStsConfig() { return STS_CONFIG_PROVISIONED; } @Override public int getAoaResultRequestMode() { return FiraParams.AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS; } @Override public boolean isControllerTheInitiator() { return true; } @Override public int getRangingRoundUsage() { return RANGING_ROUND_USAGE_DS_TWR_DEFERRED_MODE; } })401 sConfigs.put( 402 CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_RESULT_REPORT_PHASE, 403 new UwbConfiguration() { 404 405 @Override 406 public int getConfigId() { 407 return CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_RESULT_REPORT_PHASE; 408 } 409 410 @Override 411 public int getMultiNodeMode() { 412 return MULTI_NODE_MODE_UNICAST; 413 } 414 415 @Override 416 public int getStsConfig() { 417 return STS_CONFIG_PROVISIONED; 418 } 419 420 @Override 421 public int getAoaResultRequestMode() { 422 return FiraParams.AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS; 423 } 424 425 @Override 426 public boolean isControllerTheInitiator() { 427 return true; 428 } 429 430 @Override 431 public int getRangingRoundUsage() { 432 return RANGING_ROUND_USAGE_DS_TWR_DEFERRED_MODE; 433 } 434 }); 435 436 // ID_1003 properties. sConfigs.put( CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_RESULT_REPORT_PHASE_HPRF, new UwbConfiguration() { @Override public int getConfigId() { return CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_RESULT_REPORT_PHASE_HPRF; } @Override public int getMultiNodeMode() { return MULTI_NODE_MODE_UNICAST; } @Override public int getStsConfig() { return STS_CONFIG_PROVISIONED; } @Override public int getAoaResultRequestMode() { return FiraParams.AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS; } @Override public boolean isControllerTheInitiator() { return true; } @Override public int getRangingRoundUsage() { return RANGING_ROUND_USAGE_DS_TWR_DEFERRED_MODE; } })437 sConfigs.put( 438 CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_RESULT_REPORT_PHASE_HPRF, 439 new UwbConfiguration() { 440 441 @Override 442 public int getConfigId() { 443 return CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_RESULT_REPORT_PHASE_HPRF; 444 } 445 446 @Override 447 public int getMultiNodeMode() { 448 return MULTI_NODE_MODE_UNICAST; 449 } 450 451 @Override 452 public int getStsConfig() { 453 return STS_CONFIG_PROVISIONED; 454 } 455 456 @Override 457 public int getAoaResultRequestMode() { 458 return FiraParams.AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS; 459 } 460 461 @Override 462 public boolean isControllerTheInitiator() { 463 return true; 464 } 465 466 @Override 467 public int getRangingRoundUsage() { 468 return RANGING_ROUND_USAGE_DS_TWR_DEFERRED_MODE; 469 } 470 }); 471 } 472 ConfigurationManager()473 private ConfigurationManager() { 474 } 475 476 /** Creates a {@link FiraOpenSessionParams}. */ createOpenSessionParams( @iraParams.RangingDeviceType int deviceType, UwbAddress localAddress, RangingParameters rangingParameters, UwbFeatureFlags featureFlags)477 public static FiraOpenSessionParams createOpenSessionParams( 478 @FiraParams.RangingDeviceType int deviceType, 479 UwbAddress localAddress, 480 RangingParameters rangingParameters, 481 UwbFeatureFlags featureFlags) { 482 RangingTimingParams timingParams = 483 getRangingTimingParams(rangingParameters.getUwbConfigId()); 484 UwbConfiguration configuration = sConfigs.get(rangingParameters.getUwbConfigId()); 485 int deviceRole; 486 switch (deviceType) { 487 case RANGING_DEVICE_TYPE_CONTROLLER: 488 deviceRole = 489 configuration.isControllerTheInitiator() 490 ? RANGING_DEVICE_ROLE_INITIATOR 491 : RANGING_DEVICE_ROLE_RESPONDER; 492 break; 493 case RANGING_DEVICE_TYPE_CONTROLEE: 494 deviceRole = 495 configuration.isControllerTheInitiator() 496 ? RANGING_DEVICE_ROLE_RESPONDER 497 : RANGING_DEVICE_ROLE_INITIATOR; 498 break; 499 case RANGING_DEVICE_TYPE_DT_TAG: 500 deviceRole = RANGING_DEVICE_DT_TAG; 501 break; 502 default: 503 deviceRole = RANGING_DEVICE_ROLE_RESPONDER; 504 break; 505 } 506 507 // Remove this when we add support for ranging device type Dt-TAG. 508 if (configuration.getConfigId() == CONFIG_DL_TDOA_DT_TAG) { 509 deviceRole = RANGING_DEVICE_DT_TAG; 510 } 511 512 FiraOpenSessionParams.Builder builder = 513 new FiraOpenSessionParams.Builder() 514 .setProtocolVersion(PROTOCOL_VERSION_1_1) 515 .setRangingRoundUsage(configuration.getRangingRoundUsage()) 516 .setMultiNodeMode(configuration.getMultiNodeMode()) 517 .setMacAddressMode(MAC_ADDRESS_MODE_2_BYTES) 518 .setDeviceType(deviceType) 519 .setDeviceRole(deviceRole) 520 .setSessionId(rangingParameters.getSessionId()) 521 .setDeviceAddress(Conversions.convertUwbAddress(localAddress, 522 featureFlags.isReversedByteOrderFiraParams())) 523 .setAoaResultRequest(rangingParameters.isAoaDisabled() 524 ? AOA_RESULT_REQUEST_MODE_NO_AOA_REPORT : 525 configuration.getAoaResultRequestMode()) 526 .setChannelNumber(rangingParameters.getComplexChannel().getChannel()) 527 .setPreambleCodeIndex( 528 rangingParameters.getComplexChannel().getPreambleIndex()) 529 .setInitiationTime(timingParams.getInitiationTimeMs()) 530 .setSlotDurationRstu( 531 Utils.convertMsToRstu(rangingParameters.getSlotDuration())) 532 .setSlotsPerRangingRound(timingParams.getSlotPerRangingRound()) 533 .setRangingIntervalMs( 534 timingParams.getRangingInterval( 535 rangingParameters.getRangingUpdateRate())) 536 .setRangeDataNtfConfig( 537 Utils.convertToFiraNtfConfig( 538 rangingParameters 539 .getUwbRangeDataNtfConfig() 540 .getRangeDataNtfConfigType())) 541 .setRangeDataNtfProximityNear( 542 rangingParameters.getUwbRangeDataNtfConfig().getNtfProximityNear()) 543 .setRangeDataNtfProximityFar( 544 rangingParameters.getUwbRangeDataNtfConfig().getNtfProximityFar()) 545 .setInBandTerminationAttemptCount(3) 546 .setStsConfig(configuration.getStsConfig()) 547 .setRangingErrorStreakTimeoutMs(10_000L); 548 549 if (configuration.getStsConfig() == FiraParams.STS_CONFIG_STATIC) { 550 byte[] staticStsIv = 551 Arrays.copyOfRange( 552 rangingParameters.getSessionKeyInfo(), 553 VENDOR_ID_SIZE, 554 STATIC_STS_SESSION_KEY_INFO_SIZE); 555 builder.setVendorId( 556 featureFlags.isReversedByteOrderFiraParams() 557 ? Conversions.getReverseBytes( 558 Arrays.copyOf(rangingParameters.getSessionKeyInfo(), 559 VENDOR_ID_SIZE)) : 560 Arrays.copyOf(rangingParameters.getSessionKeyInfo(), 561 VENDOR_ID_SIZE)) 562 .setStaticStsIV(staticStsIv); 563 } else if (configuration.getStsConfig() == STS_CONFIG_PROVISIONED) { 564 builder.setSessionKey(rangingParameters.getSessionKeyInfo()) 565 .setIsKeyRotationEnabled(true) 566 .setKeyRotationRate(0); 567 } else if (configuration.getStsConfig() 568 == STS_CONFIG_PROVISIONED_FOR_CONTROLEE_INDIVIDUAL_KEY) { 569 builder.setSessionKey(rangingParameters.getSessionKeyInfo()) 570 .setSubSessionId(rangingParameters.getSubSessionId()) 571 .setSubsessionKey(rangingParameters.getSubSessionKeyInfo()); 572 } 573 574 if (timingParams.isHoppingEnabled()) { 575 builder.setHoppingMode(HOPPING_MODE_FIRA_HOPPING_ENABLE); 576 } 577 578 if (deviceRole != RANGING_DEVICE_DT_TAG) { 579 builder.setDestAddressList(Conversions.convertUwbAddressList( 580 rangingParameters.getPeerAddresses().toArray(new UwbAddress[0]), 581 featureFlags.isReversedByteOrderFiraParams())); 582 } else { 583 builder.setRframeConfig(RFRAME_CONFIG_SP1); 584 } 585 586 if (configuration.getConfigId() 587 == CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_RESULT_REPORT_PHASE_HPRF) { 588 builder.setPrfMode(PRF_MODE_HPRF); 589 } 590 591 if (configuration.getConfigId() == CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_RESULT_REPORT_PHASE 592 || configuration.getConfigId() 593 == CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_RESULT_REPORT_PHASE_HPRF) { 594 builder.setHasRangingResultReportMessage(false); 595 builder.setFilterType(FILTER_TYPE_NONE); 596 } 597 598 return builder.build(); 599 } 600 601 /** Creates a {@link FiraRangingReconfigureParams}. */ createReconfigureParams( @tils.UwbConfigId int configId, @FiraParams.MulticastListUpdateAction int action, UwbAddress[] peerAddresses, @Nullable int[] subSessionIdList, @Nullable byte[] subSessionKey, UwbFeatureFlags uwbFeatureFlags)602 public static FiraRangingReconfigureParams createReconfigureParams( 603 @Utils.UwbConfigId int configId, 604 @FiraParams.MulticastListUpdateAction int action, 605 UwbAddress[] peerAddresses, 606 @Nullable int[] subSessionIdList, 607 @Nullable byte[] subSessionKey, 608 UwbFeatureFlags uwbFeatureFlags) { 609 UwbConfiguration configuration = sConfigs.get(configId); 610 FiraRangingReconfigureParams.Builder builder = 611 new FiraRangingReconfigureParams.Builder() 612 .setAction(action) 613 .setAddressList( 614 Conversions.convertUwbAddressList(peerAddresses, 615 uwbFeatureFlags.isReversedByteOrderFiraParams()) 616 .toArray(new android.uwb.UwbAddress[0])); 617 if (configuration.getStsConfig() 618 == FiraParams.STS_CONFIG_DYNAMIC_FOR_CONTROLEE_INDIVIDUAL_KEY) { 619 builder.setSubSessionIdList(subSessionIdList).setSubSessionKeyList(subSessionKey); 620 } 621 return builder.build(); 622 } 623 624 /** Creates a {@link FiraControleeParams}. */ createControleeParams( @tils.UwbConfigId int configId, @FiraParams.MulticastListUpdateAction int action, UwbAddress[] peerAddresses, @Nullable int[] subSessionIdList, @Nullable byte[] subSessionKey, UwbFeatureFlags uwbFeatureFlags)625 public static FiraControleeParams createControleeParams( 626 @Utils.UwbConfigId int configId, 627 @FiraParams.MulticastListUpdateAction int action, 628 UwbAddress[] peerAddresses, 629 @Nullable int[] subSessionIdList, 630 @Nullable byte[] subSessionKey, 631 UwbFeatureFlags uwbFeatureFlags) { 632 UwbConfiguration configuration = sConfigs.get(configId); 633 FiraControleeParams.Builder builder = new FiraControleeParams.Builder(); 634 builder.setAction(action); 635 builder.setAddressList( 636 Conversions.convertUwbAddressList( 637 peerAddresses, uwbFeatureFlags.isReversedByteOrderFiraParams()) 638 .toArray(new android.uwb.UwbAddress[0])); 639 if (configuration.getStsConfig() 640 == FiraParams.STS_CONFIG_DYNAMIC_FOR_CONTROLEE_INDIVIDUAL_KEY) { 641 builder.setSubSessionIdList(subSessionIdList).setSubSessionKeyList(subSessionKey); 642 } 643 return builder.build(); 644 } 645 646 /** Creates a {@link FiraRangingReconfigureParams} with block striding set. */ createReconfigureParamsBlockStriding( int blockStridingLength)647 public static FiraRangingReconfigureParams createReconfigureParamsBlockStriding( 648 int blockStridingLength) { 649 return new FiraRangingReconfigureParams.Builder() 650 .setBlockStrideLength(blockStridingLength) 651 .build(); 652 } 653 654 /** Creates a {@link FiraRangingReconfigureParams} with range data notification configured. */ createReconfigureParamsRangeDataNtf( UwbRangeDataNtfConfig rangeDataNtfConfig)655 public static FiraRangingReconfigureParams createReconfigureParamsRangeDataNtf( 656 UwbRangeDataNtfConfig rangeDataNtfConfig) { 657 int configType = Utils.convertToFiraNtfConfig( 658 rangeDataNtfConfig.getRangeDataNtfConfigType()); 659 FiraRangingReconfigureParams.Builder builder = 660 new FiraRangingReconfigureParams.Builder().setRangeDataNtfConfig(configType); 661 662 if (configType == RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_LEVEL_TRIG 663 || configType == RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_EDGE_TRIG) { 664 builder 665 .setRangeDataProximityNear(rangeDataNtfConfig.getNtfProximityNear()) 666 .setRangeDataProximityFar(rangeDataNtfConfig.getNtfProximityFar()); 667 } 668 return builder.build(); 669 } 670 671 /** Indicates if the ID presents an unicast configuration. */ isUnicast(@tils.UwbConfigId int configId)672 public static boolean isUnicast(@Utils.UwbConfigId int configId) { 673 return sConfigs.get(configId).getMultiNodeMode() == MULTI_NODE_MODE_UNICAST; 674 } 675 } 676