1#
2#   Copyright 2016 - 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
16import pprint
17import random
18import time
19
20from acts import asserts
21from acts import base_test
22from acts import signals
23from acts.test_decorators import test_tracker_info
24from acts.test_utils.wifi import wifi_test_utils as wutils
25
26WifiEnums = wutils.WifiEnums
27
28# EAP Macros
29EAP = WifiEnums.Eap
30EapPhase2 = WifiEnums.EapPhase2
31
32# Enterprise Config Macros
33Ent = WifiEnums.Enterprise
34
35
36class WifiEnterpriseRoamingTest(base_test.BaseTestClass):
37    def setup_class(self):
38        self.dut = self.android_devices[0]
39        wutils.wifi_test_device_init(self.dut)
40        req_params = (
41            "ent_roaming_ssid",
42            "bssid_a",
43            "bssid_b",
44            "attn_vals",
45            # Expected time within which roaming should finish, in seconds.
46            "roam_interval",
47            "ca_cert",
48            "client_cert",
49            "client_key",
50            "eap_identity",
51            "eap_password",
52            "device_password")
53        self.unpack_userparams(req_params)
54        self.config_peap = {
55            Ent.EAP: int(EAP.PEAP),
56            Ent.CA_CERT: self.ca_cert,
57            Ent.IDENTITY: self.eap_identity,
58            Ent.PASSWORD: self.eap_password,
59            Ent.PHASE2: int(EapPhase2.MSCHAPV2),
60            WifiEnums.SSID_KEY: self.ent_roaming_ssid
61        }
62        self.config_tls = {
63            Ent.EAP: int(EAP.TLS),
64            Ent.CA_CERT: self.ca_cert,
65            WifiEnums.SSID_KEY: self.ent_roaming_ssid,
66            Ent.CLIENT_CERT: self.client_cert,
67            Ent.PRIVATE_KEY_ID: self.client_key,
68            Ent.IDENTITY: self.eap_identity,
69        }
70        self.config_ttls = {
71            Ent.EAP: int(EAP.TTLS),
72            Ent.CA_CERT: self.ca_cert,
73            Ent.IDENTITY: self.eap_identity,
74            Ent.PASSWORD: self.eap_password,
75            Ent.PHASE2: int(EapPhase2.MSCHAPV2),
76            WifiEnums.SSID_KEY: self.ent_roaming_ssid
77        }
78        self.config_sim = {
79            Ent.EAP: int(EAP.SIM),
80            WifiEnums.SSID_KEY: self.ent_roaming_ssid,
81        }
82        self.attn_a = self.attenuators[0]
83        self.attn_b = self.attenuators[1]
84        # Set screen lock password so ConfigStore is unlocked.
85        self.dut.droid.setDevicePassword(self.device_password)
86        self.set_attns("default")
87
88    def teardown_class(self):
89        wutils.reset_wifi(self.dut)
90        self.dut.droid.disableDevicePassword()
91        self.dut.ed.clear_all_events()
92        self.set_attns("default")
93
94    def setup_test(self):
95        self.dut.droid.wifiStartTrackingStateChange()
96        self.dut.droid.wakeLockAcquireBright()
97        self.dut.droid.wakeUpNow()
98        wutils.reset_wifi(self.dut)
99        self.dut.ed.clear_all_events()
100
101    def teardown_test(self):
102        self.dut.droid.wakeLockRelease()
103        self.dut.droid.goToSleepNow()
104        self.dut.droid.wifiStopTrackingStateChange()
105        self.set_attns("default")
106
107    def on_fail(self, test_name, begin_time):
108        self.dut.cat_adb_log(test_name, begin_time)
109
110    def set_attns(self, attn_val_name):
111        """Sets attenuation values on attenuators used in this test.
112
113        Args:
114            attn_val_name: Name of the attenuation value pair to use.
115        """
116        self.log.info("Set attenuation values to %s",
117                      self.attn_vals[attn_val_name])
118        try:
119            self.attn_a.set_atten(self.attn_vals[attn_val_name][0])
120            self.attn_b.set_atten(self.attn_vals[attn_val_name][1])
121        except:
122            self.log.exception("Failed to set attenuation values %s.",
123                           attn_val_name)
124            raise
125
126    def trigger_roaming_and_validate(self, attn_val_name, expected_con):
127        """Sets attenuators to trigger roaming and validate the DUT connected
128        to the BSSID expected.
129
130        Args:
131            attn_val_name: Name of the attenuation value pair to use.
132            expected_con: The expected info of the network to we expect the DUT
133                to roam to.
134        """
135        self.set_attns(attn_val_name)
136        self.log.info("Wait %ss for roaming to finish.", self.roam_interval)
137        time.sleep(self.roam_interval)
138        try:
139            self.dut.droid.wakeLockAcquireBright()
140            self.dut.droid.wakeUpNow()
141            wutils.verify_wifi_connection_info(self.dut, expected_con)
142            expected_bssid = expected_con[WifiEnums.BSSID_KEY]
143            self.log.info("Roamed to %s successfully", expected_bssid)
144        finally:
145            self.dut.droid.wifiLockRelease()
146            self.dut.droid.goToSleepNow()
147
148    def roaming_between_a_and_b_logic(self, config):
149        """Test roaming between two enterprise APs.
150
151        Steps:
152        1. Make bssid_a visible, bssid_b not visible.
153        2. Connect to ent_roaming_ssid. Expect DUT to connect to bssid_a.
154        3. Make bssid_a not visible, bssid_b visible.
155        4. Expect DUT to roam to bssid_b.
156        5. Make bssid_a visible, bssid_b not visible.
157        6. Expect DUT to roam back to bssid_a.
158        """
159        expected_con_to_a = {
160            WifiEnums.SSID_KEY: self.ent_roaming_ssid,
161            WifiEnums.BSSID_KEY: self.bssid_a,
162        }
163        expected_con_to_b = {
164            WifiEnums.SSID_KEY: self.ent_roaming_ssid,
165            WifiEnums.BSSID_KEY: self.bssid_b,
166        }
167        self.set_attns("a_on_b_off")
168        wutils.wifi_connect(self.dut, config)
169        wutils.verify_wifi_connection_info(self.dut, expected_con_to_a)
170        self.log.info("Roaming from %s to %s", self.bssid_a, self.bssid_b)
171        self.trigger_roaming_and_validate("b_on_a_off", expected_con_to_b)
172        self.log.info("Roaming from %s to %s", self.bssid_b, self.bssid_a)
173        self.trigger_roaming_and_validate("a_on_b_off", expected_con_to_a)
174
175    """ Tests Begin """
176
177    @test_tracker_info(uuid="b15e4b3f-841d-428d-87ac-272f29f06e14")
178    def test_roaming_with_config_tls(self):
179        self.roaming_between_a_and_b_logic(self.config_tls)
180
181    @test_tracker_info(uuid="d349cfec-b4af-48b2-88b7-744f5de25d43")
182    def test_roaming_with_config_ttls_none(self):
183        config = dict(self.config_ttls)
184        config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.NONE.value
185        self.roaming_between_a_and_b_logic(config)
186
187    @test_tracker_info(uuid="89b8161c-754e-4138-831d-5fe40f521ce4")
188    def test_roaming_with_config_ttls_pap(self):
189        config = dict(self.config_ttls)
190        config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.PAP.value
191        self.roaming_between_a_and_b_logic(config)
192
193    @test_tracker_info(uuid="d4925470-924b-4d03-8437-83e26b5f2df3")
194    def test_roaming_with_config_ttls_mschap(self):
195        config = dict(self.config_ttls)
196        config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.MSCHAP.value
197        self.roaming_between_a_and_b_logic(config)
198
199    @test_tracker_info(uuid="206b1327-dd9c-4742-8717-e7bf2a04eed6")
200    def test_roaming_with_config_ttls_mschapv2(self):
201        config = dict(self.config_ttls)
202        config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.MSCHAPV2.value
203        self.roaming_between_a_and_b_logic(config)
204
205    @test_tracker_info(uuid="c2c0168b-2933-4954-af62-fb41f42dc45a")
206    def test_roaming_with_config_ttls_gtc(self):
207        config = dict(self.config_ttls)
208        config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.GTC.value
209        self.roaming_between_a_and_b_logic(config)
210
211    @test_tracker_info(uuid="481c4102-8f5b-4fcd-95cc-5e3285f47985")
212    def test_roaming_with_config_peap_mschapv2(self):
213        config = dict(self.config_peap)
214        config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.MSCHAPV2.value
215        self.roaming_between_a_and_b_logic(config)
216
217    @test_tracker_info(uuid="404155d4-33a7-42b3-b369-5f2d63d19f16")
218    def test_roaming_with_config_peap_gtc(self):
219        config = dict(self.config_peap)
220        config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.GTC.value
221        self.roaming_between_a_and_b_logic(config)
222
223    """ Tests End """
224