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.net.MacAddress; 23 import android.net.wifi.rtt.RangingRequest; 24 import android.net.wifi.rtt.RangingResult; 25 import android.util.Log; 26 27 import java.io.PrintWriter; 28 import java.lang.annotation.Retention; 29 import java.lang.annotation.RetentionPolicy; 30 import java.util.ArrayList; 31 import java.util.List; 32 import java.util.function.Supplier; 33 34 /** 35 * Wrapper around a WifiRttController. 36 * May be initialized using a HIDL or AIDL WifiRttController. 37 */ 38 public class WifiRttController { 39 private static final String TAG = "WifiRttController"; 40 protected static final int CONVERSION_US_TO_MS = 1_000; 41 42 private IWifiRttController mWifiRttController; 43 44 /** Unknown status */ 45 public static final int FRAMEWORK_RTT_STATUS_UNKNOWN = -1; 46 /** Success */ 47 public static final int FRAMEWORK_RTT_STATUS_SUCCESS = 0; 48 /** General failure status */ 49 public static final int FRAMEWORK_RTT_STATUS_FAILURE = 1; 50 /** Target STA does not respond to request */ 51 public static final int FRAMEWORK_RTT_STATUS_FAIL_NO_RSP = 2; 52 /** Request rejected. Applies to 2-sided RTT only */ 53 public static final int FRAMEWORK_RTT_STATUS_FAIL_REJECTED = 3; 54 public static final int FRAMEWORK_RTT_STATUS_FAIL_NOT_SCHEDULED_YET = 4; 55 /** Timing measurement times out */ 56 public static final int FRAMEWORK_RTT_STATUS_FAIL_TM_TIMEOUT = 5; 57 /** Target on different channel, cannot range */ 58 public static final int FRAMEWORK_RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL = 6; 59 /** Ranging not supported */ 60 public static final int FRAMEWORK_RTT_STATUS_FAIL_NO_CAPABILITY = 7; 61 /** Request aborted for unknown reason */ 62 public static final int FRAMEWORK_RTT_STATUS_ABORTED = 8; 63 /** Invalid T1-T4 timestamp */ 64 public static final int FRAMEWORK_RTT_STATUS_FAIL_INVALID_TS = 9; 65 /** 11mc protocol failed */ 66 public static final int FRAMEWORK_RTT_STATUS_FAIL_PROTOCOL = 10; 67 /** Request could not be scheduled */ 68 public static final int FRAMEWORK_RTT_STATUS_FAIL_SCHEDULE = 11; 69 /** Responder cannot collaborate at time of request */ 70 public static final int FRAMEWORK_RTT_STATUS_FAIL_BUSY_TRY_LATER = 12; 71 /** Bad request args */ 72 public static final int FRAMEWORK_RTT_STATUS_INVALID_REQ = 13; 73 /** WiFi not enabled. */ 74 public static final int FRAMEWORK_RTT_STATUS_NO_WIFI = 14; 75 /** Responder overrides param info, cannot range with new params */ 76 public static final int FRAMEWORK_RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE = 15; 77 78 /** @hide */ 79 @IntDef(prefix = "FRAMEWORK_RTT_STATUS_", value = {FRAMEWORK_RTT_STATUS_UNKNOWN, 80 FRAMEWORK_RTT_STATUS_SUCCESS, FRAMEWORK_RTT_STATUS_FAILURE, 81 FRAMEWORK_RTT_STATUS_FAIL_NO_RSP, FRAMEWORK_RTT_STATUS_FAIL_REJECTED, 82 FRAMEWORK_RTT_STATUS_FAIL_NOT_SCHEDULED_YET, FRAMEWORK_RTT_STATUS_FAIL_TM_TIMEOUT, 83 FRAMEWORK_RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL, FRAMEWORK_RTT_STATUS_FAIL_NO_CAPABILITY, 84 FRAMEWORK_RTT_STATUS_ABORTED, FRAMEWORK_RTT_STATUS_FAIL_INVALID_TS, 85 FRAMEWORK_RTT_STATUS_FAIL_PROTOCOL, FRAMEWORK_RTT_STATUS_FAIL_SCHEDULE, 86 FRAMEWORK_RTT_STATUS_FAIL_BUSY_TRY_LATER, FRAMEWORK_RTT_STATUS_INVALID_REQ, 87 FRAMEWORK_RTT_STATUS_NO_WIFI, FRAMEWORK_RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE}) 88 @Retention(RetentionPolicy.SOURCE) 89 public @interface FrameworkRttStatus {} 90 91 /** 92 * Framework representation of RTT capabilities. 93 */ 94 public static class Capabilities { 95 // 1-sided rtt measurement is supported. 96 public boolean oneSidedRttSupported; 97 // Location configuration information supported. 98 public boolean lciSupported; 99 // Location civic records supported. 100 public boolean lcrSupported; 101 // Preamble supported, see bit mask definition above. 102 public int preambleSupported; 103 // RTT bandwidth supported. 104 public int bwSupported; 105 // Whether STA responder role is supported. 106 public boolean responderSupported; 107 // Draft 11mc version supported, including major and minor version. e.g., draft 4.3 is 43. 108 public byte mcVersion; 109 // Whether ftm rtt data collection is supported. 110 public boolean rttFtmSupported; 111 // IEEE 802.11az preamble supported, see bit mask definition above. 112 public int azPreambleSupported; 113 // IEE 802.11az RTT bandwidth supported. 114 public int azBwSupported; 115 // Whether IEEE 802.11az Non-Trigger-based (non-TB) responder mode is supported. 116 public boolean ntbInitiatorSupported; 117 // Whether IEEE 802.11az Non-Trigger-based (non-TB) responder mode is supported. 118 public boolean ntbResponderSupported; 119 Capabilities()120 public Capabilities() { 121 } 122 Capabilities(android.hardware.wifi.V1_0.RttCapabilities rttHalCapabilities)123 public Capabilities(android.hardware.wifi.V1_0.RttCapabilities rttHalCapabilities) { 124 oneSidedRttSupported = rttHalCapabilities.rttOneSidedSupported; 125 lciSupported = rttHalCapabilities.lciSupported; 126 lcrSupported = rttHalCapabilities.lcrSupported; 127 responderSupported = rttHalCapabilities.responderSupported; 128 preambleSupported = rttHalCapabilities.preambleSupport; 129 mcVersion = rttHalCapabilities.mcVersion; 130 bwSupported = rttHalCapabilities.bwSupport; 131 rttFtmSupported = rttHalCapabilities.rttFtmSupported; 132 } 133 Capabilities(android.hardware.wifi.V1_4.RttCapabilities rttHalCapabilities)134 public Capabilities(android.hardware.wifi.V1_4.RttCapabilities rttHalCapabilities) { 135 oneSidedRttSupported = rttHalCapabilities.rttOneSidedSupported; 136 lciSupported = rttHalCapabilities.lciSupported; 137 lcrSupported = rttHalCapabilities.lcrSupported; 138 responderSupported = rttHalCapabilities.responderSupported; 139 preambleSupported = rttHalCapabilities.preambleSupport; 140 mcVersion = rttHalCapabilities.mcVersion; 141 bwSupported = rttHalCapabilities.bwSupport; 142 rttFtmSupported = rttHalCapabilities.rttFtmSupported; 143 } 144 Capabilities(android.hardware.wifi.V1_6.RttCapabilities rttHalCapabilities)145 public Capabilities(android.hardware.wifi.V1_6.RttCapabilities rttHalCapabilities) { 146 oneSidedRttSupported = rttHalCapabilities.rttOneSidedSupported; 147 lciSupported = rttHalCapabilities.lciSupported; 148 lcrSupported = rttHalCapabilities.lcrSupported; 149 responderSupported = rttHalCapabilities.responderSupported; 150 preambleSupported = rttHalCapabilities.preambleSupport; 151 mcVersion = rttHalCapabilities.mcVersion; 152 bwSupported = rttHalCapabilities.bwSupport; 153 rttFtmSupported = rttHalCapabilities.rttFtmSupported; 154 } 155 Capabilities(android.hardware.wifi.RttCapabilities rttHalCapabilities)156 public Capabilities(android.hardware.wifi.RttCapabilities rttHalCapabilities) { 157 oneSidedRttSupported = rttHalCapabilities.rttOneSidedSupported; 158 lciSupported = rttHalCapabilities.lciSupported; 159 lcrSupported = rttHalCapabilities.lcrSupported; 160 responderSupported = rttHalCapabilities.responderSupported; 161 preambleSupported = rttHalCapabilities.preambleSupport; 162 mcVersion = rttHalCapabilities.mcVersion; 163 bwSupported = rttHalCapabilities.bwSupport; 164 rttFtmSupported = rttHalCapabilities.rttFtmSupported; 165 azPreambleSupported = rttHalCapabilities.azPreambleSupport; 166 azBwSupported = rttHalCapabilities.azBwSupport; 167 ntbInitiatorSupported = rttHalCapabilities.ntbInitiatorSupported; 168 ntbResponderSupported = rttHalCapabilities.ntbResponderSupported; 169 } 170 } 171 172 /** 173 * Callback to receive ranging results. 174 */ 175 public interface RttControllerRangingResultsCallback { 176 /** 177 * Called when ranging results are received from the HAL. 178 * 179 * @param cmdId Command ID specified in the original request. 180 * @param rangingResults A list of range results. 181 */ onRangingResults(int cmdId, List<RangingResult> rangingResults)182 void onRangingResults(int cmdId, List<RangingResult> rangingResults); 183 } 184 WifiRttController(@onNull android.hardware.wifi.V1_0.IWifiRttController rttController)185 public WifiRttController(@NonNull android.hardware.wifi.V1_0.IWifiRttController rttController) { 186 mWifiRttController = createWifiRttControllerHidlImplMockable(rttController); 187 } 188 WifiRttController(@onNull android.hardware.wifi.IWifiRttController rttController)189 public WifiRttController(@NonNull android.hardware.wifi.IWifiRttController rttController) { 190 mWifiRttController = createWifiRttControllerAidlImplMockable(rttController); 191 } 192 createWifiRttControllerHidlImplMockable( @onNull android.hardware.wifi.V1_0.IWifiRttController rttController)193 protected WifiRttControllerHidlImpl createWifiRttControllerHidlImplMockable( 194 @NonNull android.hardware.wifi.V1_0.IWifiRttController rttController) { 195 return new WifiRttControllerHidlImpl(rttController); 196 } 197 createWifiRttControllerAidlImplMockable( @onNull android.hardware.wifi.IWifiRttController rttController)198 protected WifiRttControllerAidlImpl createWifiRttControllerAidlImplMockable( 199 @NonNull android.hardware.wifi.IWifiRttController rttController) { 200 return new WifiRttControllerAidlImpl(rttController); 201 } 202 validateAndCall(String methodStr, T defaultVal, @NonNull Supplier<T> supplier)203 private <T> T validateAndCall(String methodStr, T defaultVal, @NonNull Supplier<T> supplier) { 204 if (mWifiRttController == null) { 205 Log.wtf(TAG, "Cannot call " + methodStr + " because mWifiRttController is null"); 206 return defaultVal; 207 } 208 return supplier.get(); 209 } 210 211 /** 212 * See comments for {@link IWifiRttController#setup()} 213 */ setup()214 public boolean setup() { 215 return validateAndCall("setup", false, 216 () -> mWifiRttController.setup()); 217 } 218 219 /** 220 * See comments for {@link IWifiRttController#enableVerboseLogging(boolean)} 221 */ enableVerboseLogging(boolean verbose)222 public void enableVerboseLogging(boolean verbose) { 223 if (mWifiRttController != null) { 224 mWifiRttController.enableVerboseLogging(verbose); 225 } 226 } 227 228 /** 229 * See comments for {@link IWifiRttController#registerRangingResultsCallback( 230 * RttControllerRangingResultsCallback)} 231 */ registerRangingResultsCallback(RttControllerRangingResultsCallback callback)232 public void registerRangingResultsCallback(RttControllerRangingResultsCallback callback) { 233 if (mWifiRttController != null) { 234 mWifiRttController.registerRangingResultsCallback(callback); 235 } 236 } 237 238 /** 239 * See comments for {@link IWifiRttController#validate()} 240 */ validate()241 public boolean validate() { 242 return validateAndCall("validate", false, 243 () -> mWifiRttController.validate()); 244 } 245 246 /** 247 * See comments for {@link IWifiRttController#getRttCapabilities()} 248 */ 249 @Nullable getRttCapabilities()250 public Capabilities getRttCapabilities() { 251 return validateAndCall("getRttCapabilities", null, 252 () -> mWifiRttController.getRttCapabilities()); 253 } 254 255 /** 256 * See comments for {@link IWifiRttController#rangeRequest(int, RangingRequest)} 257 */ rangeRequest(int cmdId, RangingRequest request)258 public boolean rangeRequest(int cmdId, RangingRequest request) { 259 return validateAndCall("rangeRequest", false, 260 () -> mWifiRttController.rangeRequest(cmdId, request)); 261 } 262 263 /** 264 * See comments for {@link IWifiRttController#rangeCancel(int, List)} 265 */ rangeCancel(int cmdId, ArrayList<MacAddress> macAddresses)266 public boolean rangeCancel(int cmdId, ArrayList<MacAddress> macAddresses) { 267 return validateAndCall("rangeCancel", false, 268 () -> mWifiRttController.rangeCancel(cmdId, macAddresses)); 269 } 270 271 /** 272 * See comments for {@link IWifiRttController#dump(PrintWriter)} 273 */ dump(PrintWriter pw)274 public void dump(PrintWriter pw) { 275 if (mWifiRttController != null) { 276 mWifiRttController.dump(pw); 277 } 278 } 279 } 280