• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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