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 com.android.server.wifi.hal; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.hardware.wifi.Akm; 23 import android.hardware.wifi.CipherSuite; 24 import android.net.MacAddress; 25 import android.net.wifi.rtt.PasnConfig; 26 import android.net.wifi.rtt.RangingRequest; 27 import android.net.wifi.rtt.RangingResult; 28 import android.util.Log; 29 30 import java.io.PrintWriter; 31 import java.lang.annotation.Retention; 32 import java.lang.annotation.RetentionPolicy; 33 import java.util.ArrayList; 34 import java.util.List; 35 import java.util.function.Supplier; 36 37 /** 38 * Wrapper around a WifiRttController. 39 * May be initialized using a HIDL or AIDL WifiRttController. 40 */ 41 public class WifiRttController { 42 private static final String TAG = "WifiRttController"; 43 protected static final int CONVERSION_US_TO_MS = 1_000; 44 45 private IWifiRttController mWifiRttController; 46 47 /** Unknown status */ 48 public static final int FRAMEWORK_RTT_STATUS_UNKNOWN = -1; 49 /** Success */ 50 public static final int FRAMEWORK_RTT_STATUS_SUCCESS = 0; 51 /** General failure status */ 52 public static final int FRAMEWORK_RTT_STATUS_FAILURE = 1; 53 /** Target STA does not respond to request */ 54 public static final int FRAMEWORK_RTT_STATUS_FAIL_NO_RSP = 2; 55 /** Request rejected. Applies to 2-sided RTT only */ 56 public static final int FRAMEWORK_RTT_STATUS_FAIL_REJECTED = 3; 57 public static final int FRAMEWORK_RTT_STATUS_FAIL_NOT_SCHEDULED_YET = 4; 58 /** Timing measurement times out */ 59 public static final int FRAMEWORK_RTT_STATUS_FAIL_TM_TIMEOUT = 5; 60 /** Target on different channel, cannot range */ 61 public static final int FRAMEWORK_RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL = 6; 62 /** Ranging not supported */ 63 public static final int FRAMEWORK_RTT_STATUS_FAIL_NO_CAPABILITY = 7; 64 /** Request aborted for unknown reason */ 65 public static final int FRAMEWORK_RTT_STATUS_ABORTED = 8; 66 /** Invalid T1-T4 timestamp */ 67 public static final int FRAMEWORK_RTT_STATUS_FAIL_INVALID_TS = 9; 68 /** 11mc protocol failed */ 69 public static final int FRAMEWORK_RTT_STATUS_FAIL_PROTOCOL = 10; 70 /** Request could not be scheduled */ 71 public static final int FRAMEWORK_RTT_STATUS_FAIL_SCHEDULE = 11; 72 /** Responder cannot collaborate at time of request */ 73 public static final int FRAMEWORK_RTT_STATUS_FAIL_BUSY_TRY_LATER = 12; 74 /** Bad request args */ 75 public static final int FRAMEWORK_RTT_STATUS_INVALID_REQ = 13; 76 /** WiFi not enabled. */ 77 public static final int FRAMEWORK_RTT_STATUS_NO_WIFI = 14; 78 /** Responder overrides param info, cannot range with new params */ 79 public static final int FRAMEWORK_RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE = 15; 80 81 /** @hide */ 82 @IntDef(prefix = "FRAMEWORK_RTT_STATUS_", value = {FRAMEWORK_RTT_STATUS_UNKNOWN, 83 FRAMEWORK_RTT_STATUS_SUCCESS, FRAMEWORK_RTT_STATUS_FAILURE, 84 FRAMEWORK_RTT_STATUS_FAIL_NO_RSP, FRAMEWORK_RTT_STATUS_FAIL_REJECTED, 85 FRAMEWORK_RTT_STATUS_FAIL_NOT_SCHEDULED_YET, FRAMEWORK_RTT_STATUS_FAIL_TM_TIMEOUT, 86 FRAMEWORK_RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL, FRAMEWORK_RTT_STATUS_FAIL_NO_CAPABILITY, 87 FRAMEWORK_RTT_STATUS_ABORTED, FRAMEWORK_RTT_STATUS_FAIL_INVALID_TS, 88 FRAMEWORK_RTT_STATUS_FAIL_PROTOCOL, FRAMEWORK_RTT_STATUS_FAIL_SCHEDULE, 89 FRAMEWORK_RTT_STATUS_FAIL_BUSY_TRY_LATER, FRAMEWORK_RTT_STATUS_INVALID_REQ, 90 FRAMEWORK_RTT_STATUS_NO_WIFI, FRAMEWORK_RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE}) 91 @Retention(RetentionPolicy.SOURCE) 92 public @interface FrameworkRttStatus {} 93 94 /** 95 * Framework representation of RTT capabilities. 96 */ 97 public static class Capabilities { 98 // 1-sided rtt measurement is supported. 99 public boolean oneSidedRttSupported; 100 // Location configuration information supported. 101 public boolean lciSupported; 102 // Location civic records supported. 103 public boolean lcrSupported; 104 // Preamble supported, see bit mask definition above. 105 public int preambleSupported; 106 // RTT bandwidth supported. 107 public int bwSupported; 108 // Whether STA responder role is supported. 109 public boolean responderSupported; 110 // Draft 11mc version supported, including major and minor version. e.g., draft 4.3 is 43. 111 public byte mcVersion; 112 // Whether ftm rtt data collection is supported. 113 public boolean rttFtmSupported; 114 // IEEE 802.11az preamble supported, see bit mask definition above. 115 public int azPreambleSupported; 116 // IEE 802.11az RTT bandwidth supported. 117 public int azBwSupported; 118 // Whether IEEE 802.11az Non-Trigger-based (non-TB) responder mode is supported. 119 public boolean ntbInitiatorSupported; 120 // Whether IEEE 802.11az Non-Trigger-based (non-TB) responder mode is supported. 121 public boolean ntbResponderSupported; 122 // Bitmap of AKM values indicating the set of supported AKMs. 123 public @PasnConfig.AkmType int akmsSupported; 124 // Bitmap of cipher values indicating the set of supported pairwise cipher suites. 125 public @PasnConfig.Cipher int cipherSuitesSupported; 126 // Whether secure HE-LTF (Long Training Field) is supported 127 public boolean secureHeLtfSupported; 128 // Whether ranging frame protection is supported 129 public boolean rangingFrameProtectionSupported; 130 // Maximum supported secure HE-LTF protocol version 131 public int maxSupportedSecureHeLtfProtocolVersion; 132 Capabilities()133 public Capabilities() { 134 } 135 Capabilities(android.hardware.wifi.V1_0.RttCapabilities rttHalCapabilities)136 public Capabilities(android.hardware.wifi.V1_0.RttCapabilities rttHalCapabilities) { 137 oneSidedRttSupported = rttHalCapabilities.rttOneSidedSupported; 138 lciSupported = rttHalCapabilities.lciSupported; 139 lcrSupported = rttHalCapabilities.lcrSupported; 140 responderSupported = rttHalCapabilities.responderSupported; 141 preambleSupported = rttHalCapabilities.preambleSupport; 142 mcVersion = rttHalCapabilities.mcVersion; 143 bwSupported = rttHalCapabilities.bwSupport; 144 rttFtmSupported = rttHalCapabilities.rttFtmSupported; 145 } 146 Capabilities(android.hardware.wifi.V1_4.RttCapabilities rttHalCapabilities)147 public Capabilities(android.hardware.wifi.V1_4.RttCapabilities rttHalCapabilities) { 148 oneSidedRttSupported = rttHalCapabilities.rttOneSidedSupported; 149 lciSupported = rttHalCapabilities.lciSupported; 150 lcrSupported = rttHalCapabilities.lcrSupported; 151 responderSupported = rttHalCapabilities.responderSupported; 152 preambleSupported = rttHalCapabilities.preambleSupport; 153 mcVersion = rttHalCapabilities.mcVersion; 154 bwSupported = rttHalCapabilities.bwSupport; 155 rttFtmSupported = rttHalCapabilities.rttFtmSupported; 156 } 157 Capabilities(android.hardware.wifi.V1_6.RttCapabilities rttHalCapabilities)158 public Capabilities(android.hardware.wifi.V1_6.RttCapabilities rttHalCapabilities) { 159 oneSidedRttSupported = rttHalCapabilities.rttOneSidedSupported; 160 lciSupported = rttHalCapabilities.lciSupported; 161 lcrSupported = rttHalCapabilities.lcrSupported; 162 responderSupported = rttHalCapabilities.responderSupported; 163 preambleSupported = rttHalCapabilities.preambleSupport; 164 mcVersion = rttHalCapabilities.mcVersion; 165 bwSupported = rttHalCapabilities.bwSupport; 166 rttFtmSupported = rttHalCapabilities.rttFtmSupported; 167 } 168 Capabilities(android.hardware.wifi.RttCapabilities rttHalCapabilities)169 public Capabilities(android.hardware.wifi.RttCapabilities rttHalCapabilities) { 170 oneSidedRttSupported = rttHalCapabilities.rttOneSidedSupported; 171 lciSupported = rttHalCapabilities.lciSupported; 172 lcrSupported = rttHalCapabilities.lcrSupported; 173 responderSupported = rttHalCapabilities.responderSupported; 174 preambleSupported = rttHalCapabilities.preambleSupport; 175 mcVersion = rttHalCapabilities.mcVersion; 176 bwSupported = rttHalCapabilities.bwSupport; 177 rttFtmSupported = rttHalCapabilities.rttFtmSupported; 178 azPreambleSupported = rttHalCapabilities.azPreambleSupport; 179 azBwSupported = rttHalCapabilities.azBwSupport; 180 ntbInitiatorSupported = rttHalCapabilities.ntbInitiatorSupported; 181 ntbResponderSupported = rttHalCapabilities.ntbResponderSupported; 182 secureHeLtfSupported = rttHalCapabilities.secureHeLtfSupported; 183 rangingFrameProtectionSupported = rttHalCapabilities.rangingFrameProtectionSupported; 184 maxSupportedSecureHeLtfProtocolVersion = 185 rttHalCapabilities.maxSupportedSecureHeLtfProtocolVersion; 186 akmsSupported = convertAkmsToFramework(rttHalCapabilities.akmsSupported); 187 cipherSuitesSupported = convertCiphersToFramework( 188 rttHalCapabilities.cipherSuitesSupported); 189 } 190 } 191 192 @PasnConfig.Cipher convertCiphersToFramework(long ciphersSupported)193 private static int convertCiphersToFramework(long ciphersSupported) { 194 @PasnConfig.Cipher int ciphers = PasnConfig.CIPHER_NONE; 195 if ((ciphersSupported & CipherSuite.GCMP_256) != 0) { 196 ciphers |= PasnConfig.CIPHER_GCMP_256; 197 } 198 if ((ciphersSupported & CipherSuite.GCMP_128) != 0) { 199 ciphers |= PasnConfig.CIPHER_GCMP_128; 200 } 201 if ((ciphersSupported & CipherSuite.CCMP_256) != 0) { 202 ciphers |= PasnConfig.CIPHER_CCMP_256; 203 } 204 if ((ciphersSupported & CipherSuite.CCMP_128) != 0) { 205 ciphers |= PasnConfig.CIPHER_CCMP_128; 206 } 207 return ciphers; 208 } 209 210 @PasnConfig.AkmType convertAkmsToFramework(long akmsSupported)211 private static int convertAkmsToFramework(long akmsSupported) { 212 @PasnConfig.AkmType int akms = PasnConfig.AKM_NONE; 213 if ((akmsSupported & Akm.FT_EAP_SHA384) != 0) { 214 akms |= PasnConfig.AKM_FT_EAP_SHA384; 215 } 216 if ((akmsSupported & Akm.FILS_EAP_SHA384) != 0) { 217 akms |= PasnConfig.AKM_FILS_EAP_SHA384; 218 } 219 if ((akmsSupported & Akm.FILS_EAP_SHA256) != 0) { 220 akms |= PasnConfig.AKM_FILS_EAP_SHA256; 221 } 222 if ((akmsSupported & Akm.FT_EAP_SHA256) != 0) { 223 akms |= PasnConfig.AKM_FT_EAP_SHA256; 224 } 225 if ((akmsSupported & Akm.FT_PSK_SHA384) != 0) { 226 akms |= PasnConfig.AKM_FT_PSK_SHA384; 227 } 228 if ((akmsSupported & Akm.FT_PSK_SHA256) != 0) { 229 akms |= PasnConfig.AKM_FT_PSK_SHA256; 230 } 231 if ((akmsSupported & Akm.SAE) != 0) { 232 akms |= PasnConfig.AKM_SAE; 233 } 234 if ((akmsSupported & Akm.PASN) != 0) { 235 akms |= PasnConfig.AKM_PASN; 236 } 237 return akms; 238 } 239 240 241 242 /** 243 * Callback to receive ranging results. 244 */ 245 public interface RttControllerRangingResultsCallback { 246 /** 247 * Called when ranging results are received from the HAL. 248 * 249 * @param cmdId Command ID specified in the original request. 250 * @param rangingResults A list of range results. 251 */ onRangingResults(int cmdId, List<RangingResult> rangingResults)252 void onRangingResults(int cmdId, List<RangingResult> rangingResults); 253 } 254 WifiRttController(@onNull android.hardware.wifi.V1_0.IWifiRttController rttController)255 public WifiRttController(@NonNull android.hardware.wifi.V1_0.IWifiRttController rttController) { 256 mWifiRttController = createWifiRttControllerHidlImplMockable(rttController); 257 } 258 WifiRttController(@onNull android.hardware.wifi.IWifiRttController rttController)259 public WifiRttController(@NonNull android.hardware.wifi.IWifiRttController rttController) { 260 mWifiRttController = createWifiRttControllerAidlImplMockable(rttController); 261 } 262 createWifiRttControllerHidlImplMockable( @onNull android.hardware.wifi.V1_0.IWifiRttController rttController)263 protected WifiRttControllerHidlImpl createWifiRttControllerHidlImplMockable( 264 @NonNull android.hardware.wifi.V1_0.IWifiRttController rttController) { 265 return new WifiRttControllerHidlImpl(rttController); 266 } 267 createWifiRttControllerAidlImplMockable( @onNull android.hardware.wifi.IWifiRttController rttController)268 protected WifiRttControllerAidlImpl createWifiRttControllerAidlImplMockable( 269 @NonNull android.hardware.wifi.IWifiRttController rttController) { 270 return new WifiRttControllerAidlImpl(rttController); 271 } 272 validateAndCall(String methodStr, T defaultVal, @NonNull Supplier<T> supplier)273 private <T> T validateAndCall(String methodStr, T defaultVal, @NonNull Supplier<T> supplier) { 274 if (mWifiRttController == null) { 275 Log.wtf(TAG, "Cannot call " + methodStr + " because mWifiRttController is null"); 276 return defaultVal; 277 } 278 return supplier.get(); 279 } 280 281 /** 282 * See comments for {@link IWifiRttController#setup()} 283 */ setup()284 public boolean setup() { 285 return validateAndCall("setup", false, 286 () -> mWifiRttController.setup()); 287 } 288 289 /** 290 * See comments for {@link IWifiRttController#enableVerboseLogging(boolean)} 291 */ enableVerboseLogging(boolean verbose)292 public void enableVerboseLogging(boolean verbose) { 293 if (mWifiRttController != null) { 294 mWifiRttController.enableVerboseLogging(verbose); 295 } 296 } 297 298 /** 299 * See comments for {@link IWifiRttController#registerRangingResultsCallback( 300 * RttControllerRangingResultsCallback)} 301 */ registerRangingResultsCallback(RttControllerRangingResultsCallback callback)302 public void registerRangingResultsCallback(RttControllerRangingResultsCallback callback) { 303 if (mWifiRttController != null) { 304 mWifiRttController.registerRangingResultsCallback(callback); 305 } 306 } 307 308 /** 309 * See comments for {@link IWifiRttController#validate()} 310 */ validate()311 public boolean validate() { 312 return validateAndCall("validate", false, 313 () -> mWifiRttController.validate()); 314 } 315 316 /** 317 * See comments for {@link IWifiRttController#getRttCapabilities()} 318 */ 319 @Nullable getRttCapabilities()320 public Capabilities getRttCapabilities() { 321 return validateAndCall("getRttCapabilities", null, 322 () -> mWifiRttController.getRttCapabilities()); 323 } 324 325 /** 326 * See comments for {@link IWifiRttController#rangeRequest(int, RangingRequest)} 327 */ rangeRequest(int cmdId, RangingRequest request)328 public boolean rangeRequest(int cmdId, RangingRequest request) { 329 return validateAndCall("rangeRequest", false, 330 () -> mWifiRttController.rangeRequest(cmdId, request)); 331 } 332 333 /** 334 * See comments for {@link IWifiRttController#rangeCancel(int, List)} 335 */ rangeCancel(int cmdId, ArrayList<MacAddress> macAddresses)336 public boolean rangeCancel(int cmdId, ArrayList<MacAddress> macAddresses) { 337 return validateAndCall("rangeCancel", false, 338 () -> mWifiRttController.rangeCancel(cmdId, macAddresses)); 339 } 340 341 /** 342 * See comments for {@link IWifiRttController#dump(PrintWriter)} 343 */ dump(PrintWriter pw)344 public void dump(PrintWriter pw) { 345 if (mWifiRttController != null) { 346 mWifiRttController.dump(pw); 347 } 348 } 349 350 /** 351 * Get optimum burst duration corresponding to a burst size. 352 * 353 * IEEE 802.11 spec, Section 11.21.6.3 Fine timing measurement procedure negotiation, burst 354 * duration is defined as 355 * 356 * Burst duration = (N_FTMPB * (K + 1)) – 1) * T_MDFTM + T_FTM + aSIFSTime + T_Ack, where 357 * - N_FTMPB is the value of the FTMs Per Burst subfield 358 * - K is the maximum number of Fine Timing Measurement frame retransmissions the 359 * responding STA might attempt 360 * - T_MDFTM is the duration indicated by the Min Delta FTM subfield of the Fine Timing 361 * Measurement Parameters field of the initial Fine Timing Measurement frame (FTM_1) 362 * - T_FTM is the duration of the initial Fine Timing Measurement frame if the FTMs Per Burst 363 * subfield of the Fine Timing Measurement Parameters field of FTM_1 is set to 1, 364 * and the duration of the non-initial Fine Timing Measurement frame otherwise 365 * T_Ack is the duration of the Ack frame expected as a response 366 * 367 * Since many of the parameters are dependent on the chip and the vendor software, framework is 368 * doing a simple conversion with experimented values. Vendor Software may override the burst 369 * duration with more optimal values. 370 * 371 * Section '9.4.2.167 Fine Timing Measurement Parameters element' defines Burst Duration 372 * subfield encoding as, 373 * +--------------------+ 374 * |Value| Represents | 375 * +--------------------+ 376 * | 0-1 | Reserved | 377 * | 2 | 250 us | 378 * | 3 | 500 us | 379 * | 4 | 1 ms | 380 * | 5 | 2 ms | 381 * | 6 | 4 ms | 382 * | 7 | 8 ms | 383 * | 8 | 16 ms | 384 * | 9 | 32 ms | 385 * | 10 | 64 ms | 386 * | 11 | 128 ms | 387 * |12-14| Reserved | 388 * | 15 | No Preference| 389 * +-----+--------------+ 390 */ getOptimumBurstDuration(int burstSize)391 public static int getOptimumBurstDuration(int burstSize) { 392 if (burstSize <= 8) return 9; // 32 ms 393 if (burstSize <= 24) return 10; // 64 ms 394 return 11; // 128 ms 395 } 396 } 397