1#!/usr/bin/env python3.4
2#
3#   Copyright 2018 - 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
17import time
18
19import acts.base_test
20import acts_contrib.test_utils.wifi.wifi_test_utils as wutils
21import acts_contrib.test_utils.tel.tel_test_utils as tutils
22
23from acts import asserts
24from acts import signals
25from acts import utils
26from acts.test_decorators import test_tracker_info
27from acts_contrib.test_utils.bt.bt_test_utils import enable_bluetooth
28from acts_contrib.test_utils.bt.bt_test_utils import pair_pri_to_sec
29from acts_contrib.test_utils.bt.bt_test_utils import clear_bonded_devices
30from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest
31from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_2G
32from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G
33
34WifiEnums = wutils.WifiEnums
35
36WAIT_FOR_AUTO_CONNECT = 40
37WAIT_BEFORE_CONNECTION = 30
38DEFAULT_TIMEOUT = 10
39PING_ADDR = 'www.google.com'
40BAND_2GHZ = 0
41BAND_5GHZ = 1
42WIFI_NETWORK_AP_CHANNEL_2G = 1
43WIFI_NETWORK_AP_CHANNEL_5G = 36
44
45
46class WifiBtStressCoexTest(WifiBaseTest):
47    """WiFi BT Coex Stress test class.
48
49    Test Bed Requirement:
50    * Two Android device
51    * One Android device with simulator BT branch code
52    * Several Wi-Fi networks visible to the device, including an open Wi-Fi
53      network.
54    """
55
56    def __init__(self, configs):
57        super().__init__(configs)
58        self.enable_packet_log = True
59
60    def setup_class(self):
61        super().setup_class()
62
63        self.dut = self.android_devices[0]
64        if len(self.android_devices) > 1:
65            self.dut_client = self.android_devices[1]
66            self.headset = self.android_devices[2]
67        else:
68            self.dut_client = None
69        wutils.wifi_test_device_init(self.dut)
70        req_params = []
71        opt_param = [
72            "open_network", "reference_networks", "iperf_server_address",
73            "stress_count", "stress_hours", "attn_vals", "pno_interval",
74            "iperf_server_port", "dbs_supported_models",
75            "sta_sta_supported_models"
76        ]
77        self.unpack_userparams(req_param_names=req_params,
78                               opt_param_names=opt_param)
79
80        self.ap_iface = 'wlan0'
81        if self.dut.model in self.dbs_supported_models:
82            self.ap_iface = 'wlan1'
83        if self.dut.model in self.sta_sta_supported_models:
84            self.ap_iface = 'wlan2'
85
86        if "AccessPoint" in self.user_params:
87            self.legacy_configure_ap_and_start(ap_count=2)
88        elif "OpenWrtAP" in self.user_params:
89            self.configure_openwrt_ap_and_start(open_network=True,
90                                                wpa_network=True,
91                                                ap_count=2)
92        asserts.assert_true(
93            len(self.reference_networks) > 0,
94            "Need at least one reference network with psk.")
95        self.wpa_2g = self.reference_networks[0]["2g"]
96        self.wpa_5g = self.reference_networks[0]["5g"]
97        self.open_2g = self.open_network[0]["2g"]
98        self.open_5g = self.open_network[0]["5g"]
99        self.networks = [self.wpa_2g, self.wpa_5g, self.open_2g, self.open_5g]
100
101    def setup_test(self):
102        super().setup_test()
103        self.dut.droid.wakeLockAcquireBright()
104        self.dut.droid.wakeUpNow()
105        wutils.wifi_toggle_state(self.dut_client, True)
106
107    def teardown_test(self):
108        super().teardown_test()
109        if self.dut.droid.wifiIsApEnabled():
110            wutils.stop_wifi_tethering(self.dut)
111        self.dut.droid.wakeLockRelease()
112        self.dut.droid.goToSleepNow()
113        wutils.reset_wifi(self.dut)
114        wutils.reset_wifi(self.dut_client)
115        clear_bonded_devices(self.dut)
116        clear_bonded_devices(self.headset)
117
118    def teardown_class(self):
119        wutils.reset_wifi(self.dut)
120        if "AccessPoint" in self.user_params:
121            del self.user_params["reference_networks"]
122            del self.user_params["open_network"]
123
124    """Helper Functions"""
125
126    def scan_and_connect_by_ssid(self, ad, network):
127        """Scan for network and connect using network information.
128
129        Args:
130            network: A dictionary representing the network to connect to.
131
132        """
133        ssid = network[WifiEnums.SSID_KEY]
134        wutils.start_wifi_connection_scan_and_ensure_network_found(ad, ssid)
135        wutils.wifi_connect(ad, network, num_of_tries=3)
136
137    def scan_and_connect_by_id(self, network, net_id):
138        """Scan for network and connect using network id.
139
140        Args:
141            net_id: Integer specifying the network id of the network.
142
143        """
144        ssid = network[WifiEnums.SSID_KEY]
145        wutils.start_wifi_connection_scan_and_ensure_network_found(
146            self.dut, ssid)
147        wutils.wifi_connect_by_id(self.dut, net_id)
148
149    def run_ping(self, sec):
150        """Run ping for given number of seconds.
151
152        Args:
153            sec: Time in seconds to run the ping traffic.
154
155        """
156        self.log.info("Running ping for %d seconds" % sec)
157        result = self.dut.adb.shell("ping -w %d %s" % (sec, PING_ADDR),
158                                    timeout=sec + 1)
159        self.log.debug("Ping Result = %s" % result)
160        if "100% packet loss" in result:
161            raise signals.TestFailure("100% packet loss during ping")
162
163    def create_softap_config(self):
164        """Create a softap config with ssid and password."""
165        ap_ssid = "softap_" + utils.rand_ascii_str(8)
166        ap_password = utils.rand_ascii_str(8)
167        self.dut.log.info("softap setup: %s %s", ap_ssid, ap_password)
168        config = {wutils.WifiEnums.SSID_KEY: ap_ssid}
169        config[wutils.WifiEnums.PWD_KEY] = ap_password
170        return config
171
172    def start_softap_and_verify(self, band, check_connectivity=True):
173        """Test startup of softap.
174
175        1. Bring up AP mode.
176        2. Verify SoftAP active using the client device.
177
178        Args:
179            band: wifi band to start soft ap on
180            check_connectivity: If set, verify internet connectivity
181
182        Returns:
183            config
184        """
185        config = self.create_softap_config()
186        wutils.start_wifi_tethering(self.dut, config[WifiEnums.SSID_KEY],
187                                    config[WifiEnums.PWD_KEY], band)
188        for ad in self.android_devices[1:]:
189            wutils.connect_to_wifi_network(
190                ad, config, check_connectivity=check_connectivity)
191        return config
192
193    def verify_softap_full_on_off(self, network, softap_band):
194        """Bring up AP mode and verify ap mode
195
196        Args:
197            softap_band: wifi band to start soft ap on
198            network: android_device to connect ap with security type
199
200        """
201        self.start_softap_and_verify(softap_band)
202        wutils.stop_wifi_tethering(self.dut)
203
204    def connect_BT_paired(self, dut, headset):
205        """Start to pairing the simulator BT device.
206
207        Args:
208            dut: Android device initiating connection
209            headset: Android device accepting connection
210
211        """
212        enable_bluetooth(dut.droid, dut.ed)
213        enable_bluetooth(headset.droid, headset.ed)
214        time.sleep(DEFAULT_TIMEOUT)
215        pair_pri_to_sec(dut, headset)
216
217    """Tests"""
218
219    @test_tracker_info(uuid="4bacb48d-1e31-4561-b7b3-8e86478a82b3")
220    def test_wifi_on_off_with_2g(self):
221        """Test wifi on/off state by connection to 2G network followed
222           with BT paired.
223        """
224        wutils.wifi_toggle_state(self.dut, True)
225        self.scan_and_connect_by_ssid(self.dut, self.wpa_2g)
226        self.connect_BT_paired(self.dut, self.headset)
227        time.sleep(5)
228        for count in range(self.stress_count):
229            """Test toggling wifi"""
230            try:
231                self.log.debug("Going from on to off.")
232                wutils.wifi_toggle_state(self.dut, False)
233                self.log.debug("Going from off to on.")
234                startTime = time.time()
235                wutils.wifi_toggle_state(self.dut, True)
236                startup_time = time.time() - startTime
237                self.log.debug("WiFi was enabled on the device in %s s." %
238                               startup_time)
239            except:
240                raise signals.TestFailure(details="",
241                                          extras={
242                                              "Iterations":
243                                              "%d" % self.stress_count,
244                                              "Pass": "%d" % count
245                                          })
246        raise signals.TestPass(details="",
247                               extras={
248                                   "Iterations": "%d" % self.stress_count,
249                                   "Pass": "%d" % (count + 1)
250                               })
251
252    @test_tracker_info(uuid="ed5b77ff-8a64-4ea7-a481-96ad3a3b91d0")
253    def test_wifi_on_off_with_5g(self):
254        """Test wifi on/off state by connection to 5G network followed
255           with BT paired.
256        """
257        wutils.wifi_toggle_state(self.dut, True)
258        self.scan_and_connect_by_ssid(self.dut, self.wpa_5g)
259        self.connect_BT_paired(self.dut, self.headset)
260        time.sleep(5)
261        for count in range(self.stress_count):
262            """Test toggling wifi"""
263            try:
264                self.log.debug("Going from on to off.")
265                wutils.wifi_toggle_state(self.dut, False)
266                self.log.debug("Going from off to on.")
267                startTime = time.time()
268                wutils.wifi_toggle_state(self.dut, True)
269                startup_time = time.time() - startTime
270                self.log.debug("WiFi was enabled on the device in %s s." %
271                               startup_time)
272            except:
273                raise signals.TestFailure(details="",
274                                          extras={
275                                              "Iterations":
276                                              "%d" % self.stress_count,
277                                              "Pass": "%d" % count
278                                          })
279        raise signals.TestPass(details="",
280                               extras={
281                                   "Iterations": "%d" % self.stress_count,
282                                   "Pass": "%d" % (count + 1)
283                               })
284
285    @test_tracker_info(uuid="cc132d79-d0ea-4f99-ba6f-0f6fbd21eba0")
286    def test_2g_sta_mode_and_hotspot_5g_on_off_stress_bt_paired(self):
287        """Tests connect to 2G network followed by SoftAp on 5G
288           with BT paired.
289        """
290        wutils.wifi_toggle_state(self.dut, True)
291        self.scan_and_connect_by_ssid(self.dut, self.open_2g)
292        self.connect_BT_paired(self.dut, self.headset)
293        time.sleep(5)
294        for count in range(self.stress_count):
295            """Test toggling softap"""
296            self.log.info("Iteration %d", count + 1)
297            self.verify_softap_full_on_off(self.open_2g, WIFI_CONFIG_APBAND_5G)
298
299    @test_tracker_info(uuid="de3903ec-9484-4302-814a-2027631d6ddb")
300    def test_2g_sta_mode_and_hotspot_2g_on_off_stress_bt_paired(self):
301        """Tests connect to 2G network followed by SoftAp on 2G
302           with BT paired.
303        """
304        wutils.wifi_toggle_state(self.dut, True)
305        self.scan_and_connect_by_ssid(self.dut, self.open_2g)
306        self.connect_BT_paired(self.dut, self.headset)
307        time.sleep(5)
308        for count in range(self.stress_count):
309            """Test toggling softap"""
310            self.log.info("Iteration %d", count + 1)
311            self.verify_softap_full_on_off(self.open_2g, WIFI_CONFIG_APBAND_2G)
312
313    @test_tracker_info(uuid="42a27ff4-aeb7-45f1-909b-e9695035fb95")
314    def test_5g_sta_mode_and_hotspot_2g_on_off_stress_bt_paired(self):
315        """Tests connect to 5G network followed by SoftAp on 2G
316           with BT paired.
317        """
318        wutils.wifi_toggle_state(self.dut, True)
319        self.scan_and_connect_by_ssid(self.dut, self.open_5g)
320        self.connect_BT_paired(self.dut, self.headset)
321        time.sleep(5)
322        for count in range(self.stress_count):
323            """Test toggling softap"""
324            self.log.info("Iteration %d", count + 1)
325            self.verify_softap_full_on_off(self.open_2g, WIFI_CONFIG_APBAND_2G)
326
327    @test_tracker_info(uuid="bae3c34b-34dd-47e4-8a6b-3b2dd97e169e")
328    def test_5g_sta_mode_and_hotspot_5g_on_off_stress_bt_paired(self):
329        """Tests connect to 5G network followed by SoftAp on 5G
330           with BT paired.
331        """
332        wutils.wifi_toggle_state(self.dut, True)
333        self.scan_and_connect_by_ssid(self.dut, self.open_5g)
334        self.connect_BT_paired(self.dut, self.headset)
335        time.sleep(5)
336        for count in range(self.stress_count):
337            """Test toggling softap"""
338            self.log.info("Iteration %d", count + 1)
339            self.verify_softap_full_on_off(self.open_2g, WIFI_CONFIG_APBAND_5G)
340
341    @test_tracker_info(uuid="4f39304b-18a1-4c54-8fa1-072ef3c1688d")
342    def test_2g_hotspot_on_off_with_bt_paired(self):
343        """Tests followed by turn on/off SoftAp on 2G with BT paired.
344        """
345        wutils.wifi_toggle_state(self.dut, True)
346        self.connect_BT_paired(self.dut, self.headset)
347        time.sleep(5)
348        for count in range(self.stress_count):
349            """Test toggling softap"""
350            self.log.info("Iteration %d", count + 1)
351            softap_config = wutils.create_softap_config()
352            wutils.start_wifi_tethering(
353                self.dut, softap_config[wutils.WifiEnums.SSID_KEY],
354                softap_config[wutils.WifiEnums.PWD_KEY],
355                wutils.WifiEnums.WIFI_CONFIG_APBAND_2G)
356            config = {
357                "SSID": softap_config[wutils.WifiEnums.SSID_KEY],
358                "password": softap_config[wutils.WifiEnums.PWD_KEY]
359            }
360            wutils.wifi_toggle_state(self.dut_client, True)
361            wutils.connect_to_wifi_network(self.dut_client,
362                                           config,
363                                           check_connectivity=False)
364            # Ping the DUT
365            dut_addr = self.dut.droid.connectivityGetIPv4Addresses(
366                self.ap_iface)[0]
367            asserts.assert_true(
368                utils.adb_shell_ping(self.dut_client,
369                                     count=10,
370                                     dest_ip=dut_addr,
371                                     timeout=20),
372                "%s ping %s failed" % (self.dut_client.serial, dut_addr))
373            wutils.wifi_toggle_state(self.dut_client, True)
374            wutils.stop_wifi_tethering(self.dut)
375
376    @test_tracker_info(uuid="a6b1fa3d-be1f-4039-807b-4f117681b2dc")
377    def test_5g_hotspot_on_off_with_bt_paired(self):
378        """Tests followed by turn on/off SoftAp on 5G with BT paired.
379        """
380        wutils.wifi_toggle_state(self.dut, True)
381        self.connect_BT_paired(self.dut, self.headset)
382        time.sleep(5)
383        for count in range(self.stress_count):
384            """Test toggling softap"""
385            self.log.info("Iteration %d", count + 1)
386            softap_config = wutils.create_softap_config()
387            wutils.start_wifi_tethering(
388                self.dut, softap_config[wutils.WifiEnums.SSID_KEY],
389                softap_config[wutils.WifiEnums.PWD_KEY],
390                wutils.WifiEnums.WIFI_CONFIG_APBAND_5G)
391            config = {
392                "SSID": softap_config[wutils.WifiEnums.SSID_KEY],
393                "password": softap_config[wutils.WifiEnums.PWD_KEY]
394            }
395            wutils.wifi_toggle_state(self.dut_client, True)
396            wutils.connect_to_wifi_network(self.dut_client,
397                                           config,
398                                           check_connectivity=False)
399            # Ping the DUT
400            dut_addr = self.dut.droid.connectivityGetIPv4Addresses(
401                self.ap_iface)[0]
402            asserts.assert_true(
403                utils.adb_shell_ping(self.dut_client,
404                                     count=10,
405                                     dest_ip=dut_addr,
406                                     timeout=20),
407                "%s ping %s failed" % (self.dut_client.serial, dut_addr))
408            wutils.wifi_toggle_state(self.dut_client, True)
409            wutils.stop_wifi_tethering(self.dut)
410