Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2018 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 android.net.wifi.rtt.cts;
     18 
     19 import android.content.IntentFilter;
     20 import android.net.wifi.ScanResult;
     21 import android.net.wifi.rtt.RangingRequest;
     22 import android.net.wifi.rtt.RangingResult;
     23 import android.net.wifi.rtt.WifiRttManager;
     24 
     25 import com.android.compatibility.common.util.DeviceReportLog;
     26 import com.android.compatibility.common.util.ResultType;
     27 import com.android.compatibility.common.util.ResultUnit;
     28 
     29 import java.util.ArrayList;
     30 import java.util.Arrays;
     31 import java.util.List;
     32 
     33 /**
     34  * Wi-Fi RTT CTS test: range to all available Access Points which support IEEE 802.11mc.
     35  */
     36 public class WifiRttTest extends TestBase {
     37     // Number of scans to do while searching for APs supporting IEEE 802.11mc
     38     private static final int NUM_SCANS_SEARCHING_FOR_IEEE80211MC_AP = 2;
     39 
     40     // Number of RTT measurements per AP
     41     private static final int NUM_OF_RTT_ITERATIONS = 10;
     42 
     43     // Maximum failure rate of RTT measurements (percentage)
     44     private static final int MAX_FAILURE_RATE_PERCENT = 10;
     45 
     46     // Maximum variation from the average measurement (measures consistency)
     47     private static final int MAX_VARIATION_FROM_AVERAGE_DISTANCE_MM = 1000;
     48 
     49     // Minimum valid RSSI value
     50     private static final int MIN_VALID_RSSI = -100;
     51 
     52     /**
     53      * Test Wi-Fi RTT ranging operation:
     54      * - Scan for visible APs for the test AP (which is validated to support IEEE 802.11mc)
     55      * - Perform N (constant) RTT operations
     56      * - Validate:
     57      *   - Failure ratio < threshold (constant)
     58      *   - Result margin < threshold (constant)
     59      */
     60     public void testRangingToTestAp() throws InterruptedException {
     61         if (!shouldTestWifiRtt(getContext())) {
     62             return;
     63         }
     64 
     65         // Scan for IEEE 802.11mc supporting APs
     66         ScanResult testAp = scanForTestAp(NUM_SCANS_SEARCHING_FOR_IEEE80211MC_AP);
     67         assertTrue("Cannot find test AP", testAp != null);
     68 
     69         // Perform RTT operations
     70         RangingRequest request = new RangingRequest.Builder().addAccessPoint(testAp).build();
     71         List<RangingResult> allResults = new ArrayList<>();
     72         int numFailures = 0;
     73         int distanceSum = 0;
     74         int distanceMin = 0;
     75         int distanceMax = 0;
     76         int[] statuses = new int[NUM_OF_RTT_ITERATIONS];
     77         int[] distanceMms = new int[NUM_OF_RTT_ITERATIONS];
     78         int[] distanceStdDevMms = new int[NUM_OF_RTT_ITERATIONS];
     79         int[] rssis = new int[NUM_OF_RTT_ITERATIONS];
     80         int[] numAttempted = new int[NUM_OF_RTT_ITERATIONS];
     81         int[] numSuccessful = new int[NUM_OF_RTT_ITERATIONS];
     82         long[] timestampsMs = new long[NUM_OF_RTT_ITERATIONS];
     83         byte[] lastLci = null;
     84         byte[] lastLcr = null;
     85         for (int i = 0; i < NUM_OF_RTT_ITERATIONS; ++i) {
     86             ResultCallback callback = new ResultCallback();
     87             mWifiRttManager.startRanging(request, mExecutor, callback);
     88             assertTrue("Wi-Fi RTT results: no callback on iteration " + i,
     89                     callback.waitForCallback());
     90 
     91             List<RangingResult> currentResults = callback.getResults();
     92             assertTrue("Wi-Fi RTT results: null results (onRangingFailure) on iteration " + i,
     93                     currentResults != null);
     94             assertTrue("Wi-Fi RTT results: unexpected # of results (expect 1) on iteration " + i,
     95                     currentResults.size() == 1);
     96             RangingResult result = currentResults.get(0);
     97             assertTrue("Wi-Fi RTT results: invalid result (wrong BSSID) entry on iteration " + i,
     98                     result.getMacAddress().toString().equals(testAp.BSSID));
     99             assertEquals(
    100                     "Wi-Fi RTT results: invalid result (non-null PeerHandle) entry on iteration "
    101                             + i, null, result.getPeerHandle());
    102 
    103             allResults.add(result);
    104             int status = result.getStatus();
    105             statuses[i] = status;
    106             if (status == RangingResult.STATUS_SUCCESS) {
    107                 distanceSum += result.getDistanceMm();
    108                 if (i == 0) {
    109                     distanceMin = result.getDistanceMm();
    110                     distanceMax = result.getDistanceMm();
    111                 } else {
    112                     distanceMin = Math.min(distanceMin, result.getDistanceMm());
    113                     distanceMax = Math.max(distanceMax, result.getDistanceMm());
    114                 }
    115 
    116                 assertTrue("Wi-Fi RTT results: invalid RSSI on iteration " + i,
    117                         result.getRssi() >= MIN_VALID_RSSI);
    118 
    119                 distanceMms[i - numFailures] = result.getDistanceMm();
    120                 distanceStdDevMms[i - numFailures] = result.getDistanceStdDevMm();
    121                 rssis[i - numFailures] = result.getRssi();
    122                 numAttempted[i - numFailures] = result.getNumAttemptedMeasurements();
    123                 numSuccessful[i - numFailures] = result.getNumSuccessfulMeasurements();
    124                 timestampsMs[i - numFailures] = result.getRangingTimestampMillis();
    125 
    126                 byte[] currentLci = result.getLci();
    127                 byte[] currentLcr = result.getLcr();
    128                 if (i - numFailures > 0) {
    129                     assertTrue("Wi-Fi RTT results: invalid result (LCI mismatch) on iteration " + i,
    130                             Arrays.equals(currentLci, lastLci));
    131                     assertTrue("Wi-Fi RTT results: invalid result (LCR mismatch) on iteration " + i,
    132                             Arrays.equals(currentLcr, lastLcr));
    133                 }
    134                 lastLci = currentLci;
    135                 lastLcr = currentLcr;
    136             } else {
    137                 numFailures++;
    138             }
    139         }
    140 
    141         // Save results to log
    142         int numGoodResults = NUM_OF_RTT_ITERATIONS - numFailures;
    143         DeviceReportLog reportLog = new DeviceReportLog(TAG, "testRangingToTestAp");
    144         reportLog.addValues("status_codes", statuses, ResultType.NEUTRAL, ResultUnit.NONE);
    145         reportLog.addValues("distance_mm", Arrays.copyOf(distanceMms, numGoodResults),
    146                 ResultType.NEUTRAL, ResultUnit.NONE);
    147         reportLog.addValues("distance_stddev_mm", Arrays.copyOf(distanceStdDevMms, numGoodResults),
    148                 ResultType.NEUTRAL, ResultUnit.NONE);
    149         reportLog.addValues("rssi_dbm", Arrays.copyOf(rssis, numGoodResults), ResultType.NEUTRAL,
    150                 ResultUnit.NONE);
    151         reportLog.addValues("num_attempted", Arrays.copyOf(numAttempted, numGoodResults),
    152                 ResultType.NEUTRAL, ResultUnit.NONE);
    153         reportLog.addValues("num_successful", Arrays.copyOf(numSuccessful, numGoodResults),
    154                 ResultType.NEUTRAL, ResultUnit.NONE);
    155         reportLog.addValues("timestamps", Arrays.copyOf(timestampsMs, numGoodResults),
    156                 ResultType.NEUTRAL, ResultUnit.NONE);
    157         reportLog.submit();
    158 
    159         // Analyze results
    160         assertTrue("Wi-Fi RTT failure rate exceeds threshold",
    161                 numFailures <= NUM_OF_RTT_ITERATIONS * MAX_FAILURE_RATE_PERCENT / 100);
    162         if (numFailures != NUM_OF_RTT_ITERATIONS) {
    163             double distanceAvg = distanceSum / (NUM_OF_RTT_ITERATIONS - numFailures);
    164             assertTrue("Wi-Fi RTT: Variation (max direction) exceeds threshold",
    165                     (distanceMax - distanceAvg) <= MAX_VARIATION_FROM_AVERAGE_DISTANCE_MM);
    166             assertTrue("Wi-Fi RTT: Variation (min direction) exceeds threshold",
    167                     (distanceAvg - distanceMin) <= MAX_VARIATION_FROM_AVERAGE_DISTANCE_MM);
    168             for (int i = 0; i < numGoodResults; ++i) {
    169                 assertNotSame("Number of attempted measurements is 0", 0, numAttempted[i]);
    170                 assertNotSame("Number of successful measurements is 0", 0, numSuccessful[i]);
    171             }
    172         }
    173     }
    174 
    175     /**
    176      * Validate that when a request contains more range operations than allowed (by API) that we
    177      * get an exception.
    178      */
    179     public void testRequestTooLarge() {
    180         if (!shouldTestWifiRtt(getContext())) {
    181             return;
    182         }
    183 
    184         ScanResult dummy = new ScanResult();
    185         dummy.BSSID = "00:01:02:03:04:05";
    186 
    187         RangingRequest.Builder builder = new RangingRequest.Builder();
    188         for (int i = 0; i < RangingRequest.getMaxPeers() - 2; ++i) {
    189             builder.addAccessPoint(dummy);
    190         }
    191 
    192         List<ScanResult> scanResults = new ArrayList<>();
    193         scanResults.add(dummy);
    194         scanResults.add(dummy);
    195         scanResults.add(dummy);
    196 
    197         builder.addAccessPoints(scanResults);
    198 
    199         try {
    200             mWifiRttManager.startRanging(builder.build(), mExecutor, new ResultCallback());
    201         } catch (IllegalArgumentException e) {
    202             return;
    203         }
    204 
    205         assertTrue(
    206                 "Did not receive expected IllegalArgumentException when tried to range to too "
    207                         + "many peers",
    208                 false);
    209     }
    210 }
    211