1#!/usr/bin/python3.4
2#
3#   Copyright 2017 - The Android Open Source Project
4#
5#   Licensed under the Apache License, Version 2.0 (the "License");
6#   you may not use this file except in compliance with the License.
7#   You may obtain a copy of the License at
8#
9#       http://www.apache.org/licenses/LICENSE-2.0
10#
11#   Unless required by applicable law or agreed to in writing, software
12#   distributed under the License is distributed on an "AS IS" BASIS,
13#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14#   See the License for the specific language governing permissions and
15#   limitations under the License.
16
17from acts import asserts
18from acts.test_decorators import test_tracker_info
19from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest
20from acts.test_utils.wifi.rtt import rtt_const as rconsts
21from acts.test_utils.wifi.rtt import rtt_test_utils as rutils
22from acts.test_utils.wifi.rtt.RttBaseTest import RttBaseTest
23
24
25class RangeApNonSupporting11McTest(WifiBaseTest, RttBaseTest):
26  """Test class for RTT ranging to Access Points which do not support IEEE
27  802.11mc"""
28
29  # Number of RTT iterations
30  NUM_ITER = 10
31
32  # Time gap (in seconds) between iterations
33  TIME_BETWEEN_ITERATIONS = 0
34
35  def __init__(self, controllers):
36    WifiBaseTest.__init__(self, controllers)
37    RttBaseTest.__init__(self, controllers)
38    if "AccessPoint" in self.user_params:
39      self.legacy_configure_ap_and_start()
40
41  #############################################################################
42
43  @test_tracker_info(uuid="cde756e9-11f3-43da-b9ae-9edf85764f82")
44  def test_rtt_non_80211mc_supporting_aps(self):
45    """Scan for APs and perform RTT on non-IEEE 802.11mc supporting APs"""
46    dut = self.android_devices[0]
47    non_rtt_aps = rutils.select_best_scan_results(
48      rutils.scan_with_rtt_support_constraint(dut, False), select_count=1)
49    dut.log.debug("Visible non-IEEE 802.11mc APs=%s", non_rtt_aps)
50    asserts.assert_true(len(non_rtt_aps) > 0, "Need at least one AP!")
51    events = rutils.run_ranging(dut, non_rtt_aps, self.NUM_ITER,
52                                self.TIME_BETWEEN_ITERATIONS)
53    stats = rutils.analyze_results(events, self.rtt_reference_distance_mm,
54                                   self.rtt_reference_distance_margin_mm,
55                                   self.rtt_min_expected_rssi_dbm,
56                                   self.lci_reference, self.lcr_reference)
57    dut.log.debug("Stats=%s", stats)
58
59    for bssid, stat in stats.items():
60      asserts.assert_true(stat['num_no_results'] == 0,
61                          "Missing (timed-out) results", extras=stats)
62      asserts.assert_false(stat['any_lci_mismatch'],
63                           "LCI mismatch", extras=stats)
64      asserts.assert_false(stat['any_lcr_mismatch'],
65                           "LCR mismatch", extras=stats)
66      asserts.assert_equal(stat['num_invalid_rssi'], 0, "Invalid RSSI",
67                          extras=stats)
68      asserts.assert_true(stat['num_failures'] <=
69                          self.rtt_max_failure_rate_one_sided_rtt_percentage
70                          * stat['num_results'] / 100,
71                          "Failure rate is too high", extras=stats)
72      asserts.assert_true(stat['num_range_out_of_margin'] <=
73                self.rtt_max_margin_exceeded_rate_one_sided_rtt_percentage
74                          * stat['num_success_results'] / 100,
75                "Results exceeding error margin rate is too high",
76                extras=stats)
77    asserts.explicit_pass("RTT test done", extras=stats)
78
79  @test_tracker_info(uuid="c9e22185-16d4-4fe6-894f-5823587b3288")
80  def test_rtt_non_80211mc_supporting_aps_wo_privilege(self):
81    """Scan for APs and perform RTT on non-IEEE 802.11mc supporting APs with the
82    device not having privilege access (expect failures)."""
83    dut = self.android_devices[0]
84    rutils.config_privilege_override(dut, True)
85    non_rtt_aps = rutils.select_best_scan_results(
86      rutils.scan_with_rtt_support_constraint(dut, False), select_count=1)
87    dut.log.debug("Visible non-IEEE 802.11mc APs=%s", non_rtt_aps)
88    asserts.assert_true(len(non_rtt_aps) > 0, "Need at least one AP!")
89    events = rutils.run_ranging(dut, non_rtt_aps, self.NUM_ITER,
90                                self.TIME_BETWEEN_ITERATIONS)
91    stats = rutils.analyze_results(events, self.rtt_reference_distance_mm,
92                                   self.rtt_reference_distance_margin_mm,
93                                   self.rtt_min_expected_rssi_dbm,
94                                   self.lci_reference, self.lcr_reference)
95    dut.log.debug("Stats=%s", stats)
96
97    for bssid, stat in stats.items():
98      asserts.assert_true(stat['num_no_results'] == 0,
99                          "Missing (timed-out) results", extras=stats)
100      asserts.assert_true(stat['num_failures'] == self.NUM_ITER,
101        "All one-sided RTT requests must fail when executed without privilege",
102                          extras=stats)
103      for code in stat['status_codes']:
104        asserts.assert_true(code ==
105        rconsts.EVENT_CB_RANGING_STATUS_RESPONDER_DOES_NOT_SUPPORT_IEEE80211MC,
106                            "Expected non-support error code", extras=stats)
107    asserts.explicit_pass("RTT test done", extras=stats)
108
109  @test_tracker_info(uuid="e117af56-bd3f-40ae-a2fd-4175f0daa7fa")
110  def test_rtt_non_80211mc_supporting_ap_faked_as_supporting(self):
111    """Scan for APs which do not support IEEE 802.11mc, maliciously modify the
112    Responder config to indicate support and pass-through to service. Verify
113    that get an error result.
114    """
115    dut = self.android_devices[0]
116    non_rtt_aps = rutils.select_best_scan_results(
117      rutils.scan_with_rtt_support_constraint(dut, False), select_count=1)
118    dut.log.debug("Visible non-IEEE 802.11mc APs=%s", non_rtt_aps)
119    asserts.assert_true(len(non_rtt_aps) > 0, "Need at least one AP!")
120    non_rtt_aps = non_rtt_aps[0:1] # pick first
121    non_rtt_aps[0][rconsts.SCAN_RESULT_KEY_RTT_RESPONDER] = True # falsify
122    dut.log.debug("Visible non-IEEE 802.11mc APs=%s", non_rtt_aps)
123    events = rutils.run_ranging(dut, non_rtt_aps, self.NUM_ITER,
124                                self.TIME_BETWEEN_ITERATIONS)
125    stats = rutils.analyze_results(events, self.rtt_reference_distance_mm,
126                                   self.rtt_reference_distance_margin_mm,
127                                   self.rtt_min_expected_rssi_dbm,
128                                   self.lci_reference, self.lcr_reference)
129    dut.log.debug("Stats=%s", stats)
130
131    for bssid, stat in stats.items():
132      asserts.assert_true(stat['num_no_results'] == 0,
133                          "Missing (timed-out) results", extras=stats)
134      asserts.assert_true(stat['num_failures'] == self.NUM_ITER,
135                          "Failures expected for falsified responder config",
136                          extras=stats)
137    asserts.explicit_pass("RTT test done", extras=stats)
138