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