• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3.4
2#
3#   Copyright 2016 - 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 logging
18import queue
19import random
20import time
21
22from acts import asserts
23from acts import utils
24from acts.test_decorators import test_tracker_info
25from acts.test_utils.net import socket_test_utils as sutils
26from acts.test_utils.tel import tel_defines
27from acts.test_utils.tel import tel_test_utils as tel_utils
28from acts.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_2G
29from acts.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G
30from acts.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_AUTO
31from acts.test_utils.wifi import wifi_constants
32from acts.test_utils.wifi import wifi_test_utils as wutils
33from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest
34
35WifiEnums = wutils.WifiEnums
36
37class WifiSoftApTest(WifiBaseTest):
38
39    def setup_class(self):
40        """It will setup the required dependencies from config file and configure
41           the devices for softap mode testing.
42
43        Returns:
44            True if successfully configured the requirements for testing.
45        """
46        super().setup_class()
47        self.dut = self.android_devices[0]
48        self.dut_client = self.android_devices[1]
49        req_params = ["dbs_supported_models"]
50        opt_param = ["open_network"]
51        self.unpack_userparams(
52            req_param_names=req_params, opt_param_names=opt_param)
53        if "AccessPoint" in self.user_params:
54            self.legacy_configure_ap_and_start()
55        elif "OpenWrtAP" in self.user_params:
56            self.configure_openwrt_ap_and_start(open_network=True)
57        self.open_network = self.open_network[0]["2g"]
58        # Do a simple version of init - mainly just sync the time and enable
59        # verbose logging.  This test will fail if the DUT has a sim and cell
60        # data is disabled.  We would also like to test with phones in less
61        # constrained states (or add variations where we specifically
62        # constrain).
63        utils.require_sl4a((self.dut, self.dut_client))
64        utils.sync_device_time(self.dut)
65        utils.sync_device_time(self.dut_client)
66        # Set country code explicitly to "US".
67        wutils.set_wifi_country_code(self.dut, wutils.WifiEnums.CountryCode.US)
68        wutils.set_wifi_country_code(self.dut_client, wutils.WifiEnums.CountryCode.US)
69        # Enable verbose logging on the duts
70        self.dut.droid.wifiEnableVerboseLogging(1)
71        asserts.assert_equal(self.dut.droid.wifiGetVerboseLoggingLevel(), 1,
72            "Failed to enable WiFi verbose logging on the softap dut.")
73        self.dut_client.droid.wifiEnableVerboseLogging(1)
74        asserts.assert_equal(self.dut_client.droid.wifiGetVerboseLoggingLevel(), 1,
75            "Failed to enable WiFi verbose logging on the client dut.")
76        wutils.wifi_toggle_state(self.dut, True)
77        wutils.wifi_toggle_state(self.dut_client, True)
78        self.AP_IFACE = 'wlan0'
79        if self.dut.model in self.dbs_supported_models:
80            self.AP_IFACE = 'wlan1'
81        if len(self.android_devices) > 2:
82            utils.sync_device_time(self.android_devices[2])
83            wutils.set_wifi_country_code(self.android_devices[2], wutils.WifiEnums.CountryCode.US)
84            self.android_devices[2].droid.wifiEnableVerboseLogging(1)
85            asserts.assert_equal(self.android_devices[2].droid.wifiGetVerboseLoggingLevel(), 1,
86                "Failed to enable WiFi verbose logging on the client dut.")
87            self.dut_client_2 = self.android_devices[2]
88
89    def teardown_class(self):
90        if self.dut.droid.wifiIsApEnabled():
91            wutils.stop_wifi_tethering(self.dut)
92        wutils.reset_wifi(self.dut)
93        wutils.reset_wifi(self.dut_client)
94        if "AccessPoint" in self.user_params:
95            del self.user_params["reference_networks"]
96            del self.user_params["open_network"]
97
98    def setup_test(self):
99        super().setup_test()
100        for ad in self.android_devices:
101            wutils.wifi_toggle_state(ad, True)
102
103    def teardown_test(self):
104        super().teardown_test()
105        self.dut.log.debug("Toggling Airplane mode OFF.")
106        asserts.assert_true(utils.force_airplane_mode(self.dut, False),
107                            "Can not turn off airplane mode: %s" % self.dut.serial)
108        if self.dut.droid.wifiIsApEnabled():
109            wutils.stop_wifi_tethering(self.dut)
110        wutils.set_wifi_country_code(self.dut, wutils.WifiEnums.CountryCode.US)
111
112    """ Helper Functions """
113    def create_softap_config(self):
114        """Create a softap config with ssid and password."""
115        ap_ssid = "softap_" + utils.rand_ascii_str(8)
116        ap_password = utils.rand_ascii_str(8)
117        self.dut.log.info("softap setup: %s %s", ap_ssid, ap_password)
118        config = {wutils.WifiEnums.SSID_KEY: ap_ssid}
119        config[wutils.WifiEnums.PWD_KEY] = ap_password
120        return config
121
122    def confirm_softap_in_scan_results(self, ap_ssid):
123        """Confirm the ap started by wifi tethering is seen in scan results.
124
125        Args:
126            ap_ssid: SSID of the ap we are looking for.
127        """
128        wutils.start_wifi_connection_scan_and_ensure_network_found(
129            self.dut_client, ap_ssid);
130
131    def confirm_softap_not_in_scan_results(self, ap_ssid):
132        """Confirm the ap started by wifi tethering is not seen in scan results.
133
134        Args:
135            ap_ssid: SSID of the ap we are looking for.
136        """
137        wutils.start_wifi_connection_scan_and_ensure_network_not_found(
138            self.dut_client, ap_ssid);
139
140    def check_cell_data_and_enable(self):
141        """Make sure that cell data is enabled if there is a sim present.
142
143        If a sim is active, cell data needs to be enabled to allow provisioning
144        checks through (when applicable).  This is done to relax hardware
145        requirements on DUTs - without this check, running this set of tests
146        after other wifi tests may cause failures.
147        """
148        # We do have a sim.  Make sure data is enabled so we can tether.
149        if not self.dut.droid.telephonyIsDataEnabled():
150            self.dut.log.info("need to enable data")
151            self.dut.droid.telephonyToggleDataConnection(True)
152            asserts.assert_true(self.dut.droid.telephonyIsDataEnabled(),
153                                "Failed to enable cell data for softap dut.")
154
155    def validate_full_tether_startup(self, band=None, hidden=None,
156                                     test_ping=False, test_clients=None):
157        """Test full startup of wifi tethering
158
159        1. Report current state.
160        2. Switch to AP mode.
161        3. verify SoftAP active.
162        4. Shutdown wifi tethering.
163        5. verify back to previous mode.
164        """
165        initial_wifi_state = self.dut.droid.wifiCheckState()
166        initial_cell_state = tel_utils.is_sim_ready(self.log, self.dut)
167        self.dut.log.info("current state: %s", initial_wifi_state)
168        self.dut.log.info("is sim ready? %s", initial_cell_state)
169        if initial_cell_state:
170            self.check_cell_data_and_enable()
171        config = self.create_softap_config()
172        wutils.start_wifi_tethering(self.dut,
173                                    config[wutils.WifiEnums.SSID_KEY],
174                                    config[wutils.WifiEnums.PWD_KEY], band, hidden)
175        if hidden:
176            # First ensure it's not seen in scan results.
177            self.confirm_softap_not_in_scan_results(
178                config[wutils.WifiEnums.SSID_KEY])
179            # If the network is hidden, it should be saved on the client to be
180            # seen in scan results.
181            config[wutils.WifiEnums.HIDDEN_KEY] = True
182            ret = self.dut_client.droid.wifiAddNetwork(config)
183            asserts.assert_true(ret != -1, "Add network %r failed" % config)
184            self.dut_client.droid.wifiEnableNetwork(ret, 0)
185        self.confirm_softap_in_scan_results(config[wutils.WifiEnums.SSID_KEY])
186        if test_ping:
187            self.validate_ping_between_softap_and_client(config)
188        if test_clients:
189            if len(self.android_devices) > 2:
190                self.validate_ping_between_two_clients(config)
191        wutils.stop_wifi_tethering(self.dut)
192        asserts.assert_false(self.dut.droid.wifiIsApEnabled(),
193                             "SoftAp is still reported as running")
194        if initial_wifi_state:
195            wutils.wait_for_wifi_state(self.dut, True)
196        elif self.dut.droid.wifiCheckState():
197            asserts.fail("Wifi was disabled before softap and now it is enabled")
198
199    def validate_ping_between_softap_and_client(self, config):
200        """Test ping between softap and its client.
201
202        Connect one android device to the wifi hotspot.
203        Verify they can ping each other.
204
205        Args:
206            config: wifi network config with SSID, password
207        """
208        wutils.wifi_connect(self.dut_client, config, check_connectivity=False)
209
210        dut_ip = self.dut.droid.connectivityGetIPv4Addresses(self.AP_IFACE)[0]
211        dut_client_ip = self.dut_client.droid.connectivityGetIPv4Addresses('wlan0')[0]
212
213        self.dut.log.info("Try to ping %s" % dut_client_ip)
214        asserts.assert_true(
215            utils.adb_shell_ping(self.dut, count=10, dest_ip=dut_client_ip, timeout=20),
216            "%s ping %s failed" % (self.dut.serial, dut_client_ip))
217
218        self.dut_client.log.info("Try to ping %s" % dut_ip)
219        asserts.assert_true(
220            utils.adb_shell_ping(self.dut_client, count=10, dest_ip=dut_ip, timeout=20),
221            "%s ping %s failed" % (self.dut_client.serial, dut_ip))
222
223        wutils.stop_wifi_tethering(self.dut)
224
225    def validate_ping_between_two_clients(self, config):
226        """Test ping between softap's clients.
227
228        Connect two android device to the wifi hotspot.
229        Verify the clients can ping each other.
230
231        Args:
232            config: wifi network config with SSID, password
233        """
234        # Connect DUT to Network
235        ad1 = self.dut_client
236        ad2 = self.android_devices[2]
237
238        wutils.wifi_connect(ad1, config, check_connectivity=False)
239        wutils.wifi_connect(ad2, config, check_connectivity=False)
240        ad1_ip = ad1.droid.connectivityGetIPv4Addresses('wlan0')[0]
241        ad2_ip = ad2.droid.connectivityGetIPv4Addresses('wlan0')[0]
242
243        # Ping each other
244        ad1.log.info("Try to ping %s" % ad2_ip)
245        asserts.assert_true(
246            utils.adb_shell_ping(ad1, count=10, dest_ip=ad2_ip, timeout=20),
247            "%s ping %s failed" % (ad1.serial, ad2_ip))
248
249        ad2.log.info("Try to ping %s" % ad1_ip)
250        asserts.assert_true(
251            utils.adb_shell_ping(ad2, count=10, dest_ip=ad1_ip, timeout=20),
252            "%s ping %s failed" % (ad2.serial, ad1_ip))
253
254    """ Tests Begin """
255
256    @test_tracker_info(uuid="495f1252-e440-461c-87a7-2c45f369e129")
257    def test_check_wifi_tethering_supported(self):
258        """Test check for wifi tethering support.
259
260         1. Call method to check if wifi hotspot is supported
261        """
262        # TODO(silberst): wifiIsPortableHotspotSupported() is currently failing.
263        # Remove the extra check and logging when b/30800811 is resolved
264        hotspot_supported = self.dut.droid.wifiIsPortableHotspotSupported()
265        tethering_supported = self.dut.droid.connectivityIsTetheringSupported()
266        self.log.info(
267            "IsPortableHotspotSupported: %s, IsTetheringSupported %s." % (
268            hotspot_supported, tethering_supported))
269        asserts.assert_true(hotspot_supported,
270                            "DUT should support wifi tethering but is reporting false.")
271        asserts.assert_true(tethering_supported,
272                            "DUT should also support wifi tethering when called from ConnectivityManager")
273
274    @test_tracker_info(uuid="09c19c35-c708-48a5-939b-ac2bbb403d54")
275    def test_full_tether_startup(self):
276        """Test full startup of wifi tethering in default band.
277
278        1. Report current state.
279        2. Switch to AP mode.
280        3. verify SoftAP active.
281        4. Shutdown wifi tethering.
282        5. verify back to previous mode.
283        """
284        self.validate_full_tether_startup()
285
286    @test_tracker_info(uuid="6437727d-7db1-4f69-963e-f26a7797e47f")
287    def test_full_tether_startup_2G(self):
288        """Test full startup of wifi tethering in 2G band.
289
290        1. Report current state.
291        2. Switch to AP mode.
292        3. verify SoftAP active.
293        4. Shutdown wifi tethering.
294        5. verify back to previous mode.
295        """
296        self.validate_full_tether_startup(WIFI_CONFIG_APBAND_2G)
297
298    @test_tracker_info(uuid="970272fa-1302-429b-b261-51efb4dad779")
299    def test_full_tether_startup_5G(self):
300        """Test full startup of wifi tethering in 5G band.
301
302        1. Report current state.
303        2. Switch to AP mode.
304        3. verify SoftAP active.
305        4. Shutdown wifi tethering.
306        5. verify back to previous mode.
307        """
308        self.validate_full_tether_startup(WIFI_CONFIG_APBAND_5G)
309
310    @test_tracker_info(uuid="f76ed37a-519a-48b4-b260-ee3fc5a9cae0")
311    def test_full_tether_startup_auto(self):
312        """Test full startup of wifi tethering in auto-band.
313
314        1. Report current state.
315        2. Switch to AP mode.
316        3. verify SoftAP active.
317        4. Shutdown wifi tethering.
318        5. verify back to previous mode.
319        """
320        self.validate_full_tether_startup(WIFI_CONFIG_APBAND_AUTO)
321
322    @test_tracker_info(uuid="d26ee4df-5dcb-4191-829f-05a10b1218a7")
323    def test_full_tether_startup_2G_hidden(self):
324        """Test full startup of wifi tethering in 2G band using hidden AP.
325
326        1. Report current state.
327        2. Switch to AP mode.
328        3. verify SoftAP active.
329        4. Shutdown wifi tethering.
330        5. verify back to previous mode.
331        """
332        self.validate_full_tether_startup(WIFI_CONFIG_APBAND_2G, True)
333
334    @test_tracker_info(uuid="229cd585-a789-4c9a-8948-89fa72de9dd5")
335    def test_full_tether_startup_5G_hidden(self):
336        """Test full startup of wifi tethering in 5G band using hidden AP.
337
338        1. Report current state.
339        2. Switch to AP mode.
340        3. verify SoftAP active.
341        4. Shutdown wifi tethering.
342        5. verify back to previous mode.
343        """
344        self.validate_full_tether_startup(WIFI_CONFIG_APBAND_5G, True)
345
346    @test_tracker_info(uuid="d546a143-6047-4ffd-b3c6-5ec81a38001f")
347    def test_full_tether_startup_auto_hidden(self):
348        """Test full startup of wifi tethering in auto-band using hidden AP.
349
350        1. Report current state.
351        2. Switch to AP mode.
352        3. verify SoftAP active.
353        4. Shutdown wifi tethering.
354        5. verify back to previous mode.
355        """
356        self.validate_full_tether_startup(WIFI_CONFIG_APBAND_AUTO, True)
357
358    @test_tracker_info(uuid="b2f75330-bf33-4cdd-851a-de390f891ef7")
359    def test_tether_startup_while_connected_to_a_network(self):
360        """Test full startup of wifi tethering in auto-band while the device
361        is connected to a network.
362
363        1. Connect to an open network.
364        2. Turn on AP mode (in auto band).
365        3. Verify SoftAP active.
366        4. Make a client connect to the AP.
367        5. Shutdown wifi tethering.
368        6. Ensure that the client disconnected.
369        """
370        wutils.wifi_toggle_state(self.dut, True)
371        wutils.wifi_connect(self.dut, self.open_network)
372        config = self.create_softap_config()
373        wutils.start_wifi_tethering(self.dut,
374                                    config[wutils.WifiEnums.SSID_KEY],
375                                    config[wutils.WifiEnums.PWD_KEY],
376                                    WIFI_CONFIG_APBAND_AUTO)
377        asserts.assert_true(self.dut.droid.wifiIsApEnabled(),
378                             "SoftAp is not reported as running")
379        # local hotspot may not have internet connectivity
380        self.confirm_softap_in_scan_results(config[wutils.WifiEnums.SSID_KEY])
381        wutils.wifi_connect(self.dut_client, config, check_connectivity=False)
382        wutils.stop_wifi_tethering(self.dut)
383        wutils.wait_for_disconnect(self.dut_client)
384
385    @test_tracker_info(uuid="f2cf56ad-b8b9-43b6-ab15-a47b1d96b92e")
386    def test_full_tether_startup_2G_with_airplane_mode_on(self):
387        """Test full startup of wifi tethering in 2G band with
388        airplane mode on.
389
390        1. Turn on airplane mode.
391        2. Report current state.
392        3. Switch to AP mode.
393        4. verify SoftAP active.
394        5. Shutdown wifi tethering.
395        6. verify back to previous mode.
396        7. Turn off airplane mode.
397        """
398        self.dut.log.debug("Toggling Airplane mode ON.")
399        asserts.assert_true(utils.force_airplane_mode(self.dut, True),
400                            "Can not turn on airplane mode: %s" % self.dut.serial)
401        wutils.wifi_toggle_state(self.dut, True)
402        self.validate_full_tether_startup(WIFI_CONFIG_APBAND_2G)
403
404    @test_tracker_info(uuid="883dd5b1-50c6-4958-a50f-bb4bea77ccaf")
405    def test_full_tether_startup_2G_one_client_ping_softap(self):
406        """(AP) 1 Device can connect to 2G hotspot
407
408        Steps:
409        1. Turn on DUT's 2G softap
410        2. Client connects to the softap
411        3. Client and DUT ping each other
412        """
413        self.validate_full_tether_startup(WIFI_CONFIG_APBAND_2G, test_ping=True)
414
415    @test_tracker_info(uuid="6604e848-99d6-422c-9fdc-2882642438b6")
416    def test_full_tether_startup_5G_one_client_ping_softap(self):
417        """(AP) 1 Device can connect to 5G hotspot
418
419        Steps:
420        1. Turn on DUT's 5G softap
421        2. Client connects to the softap
422        3. Client and DUT ping each other
423        """
424        self.validate_full_tether_startup(WIFI_CONFIG_APBAND_5G, test_ping=True)
425
426    @test_tracker_info(uuid="17725ecd-f900-4cf7-8b2d-d7515b0a595c")
427    def test_softap_2G_two_clients_ping_each_other(self):
428        """Test for 2G hotspot with 2 clients
429
430        1. Turn on 2G hotspot
431        2. Two clients connect to the hotspot
432        3. Two clients ping each other
433        """
434        asserts.skip_if(len(self.android_devices) < 3,
435                        "No extra android devices. Skip test")
436        self.validate_full_tether_startup(WIFI_CONFIG_APBAND_2G, test_clients=True)
437
438    @test_tracker_info(uuid="98c09888-1021-4f79-9065-b3cf9b132146")
439    def test_softap_5G_two_clients_ping_each_other(self):
440        """Test for 5G hotspot with 2 clients
441
442        1. Turn on 5G hotspot
443        2. Two clients connect to the hotspot
444        3. Two clients ping each other
445        """
446        asserts.skip_if(len(self.android_devices) < 3,
447                        "No extra android devices. Skip test")
448        self.validate_full_tether_startup(WIFI_CONFIG_APBAND_5G, test_clients=True)
449
450    @test_tracker_info(uuid="b991129e-030a-4998-9b08-0687270bec24")
451    def test_number_of_softap_clients(self):
452        """Test for number of softap clients to be updated correctly
453
454        1. Turn of hotspot
455        2. Register softap callback
456        3. Let client connect to the hotspot
457        4. Register second softap callback
458        5. Force client connect/disconnect to hotspot
459        6. Unregister second softap callback
460        7. Force second client connect to hotspot (if supported)
461        8. Turn off hotspot
462        9. Verify second softap callback doesn't respond after unregister
463        """
464        config = wutils.start_softap_and_verify(self, WIFI_CONFIG_APBAND_AUTO)
465        # Register callback after softap enabled to avoid unnecessary callback
466        # impact the test
467        callbackId = self.dut.droid.registerSoftApCallback()
468        # Verify clients will update immediately after register callback
469        wutils.wait_for_expected_number_of_softap_clients(
470                self.dut, callbackId, 0)
471        wutils.wait_for_expected_softap_state(self.dut, callbackId,
472                wifi_constants.WIFI_AP_ENABLED_STATE)
473
474        # Force DUTs connect to Network
475        wutils.wifi_connect(self.dut_client, config,
476                check_connectivity=False)
477        wutils.wait_for_expected_number_of_softap_clients(
478                self.dut, callbackId, 1)
479
480        # Register another callback to verify multi callback clients case
481        callbackId_2 = self.dut.droid.registerSoftApCallback()
482        # Verify clients will update immediately after register callback
483        wutils.wait_for_expected_number_of_softap_clients(
484                self.dut, callbackId_2, 1)
485        wutils.wait_for_expected_softap_state(self.dut, callbackId_2,
486                wifi_constants.WIFI_AP_ENABLED_STATE)
487
488        # Client Off/On Wifi to verify number of softap clients will be updated
489        wutils.toggle_wifi_and_wait_for_reconnection(self.dut_client, config)
490
491        wutils.wait_for_expected_number_of_softap_clients(self.dut,
492                callbackId, 0)
493        wutils.wait_for_expected_number_of_softap_clients(self.dut,
494                callbackId_2, 0)
495        wutils.wait_for_expected_number_of_softap_clients(self.dut,
496                callbackId, 1)
497        wutils.wait_for_expected_number_of_softap_clients(self.dut,
498                callbackId_2, 1)
499
500        # Unregister callbackId_2 to verify multi callback clients case
501        self.dut.droid.unregisterSoftApCallback(callbackId_2)
502
503        if len(self.android_devices) > 2:
504            wutils.wifi_connect(self.android_devices[2], config,
505                    check_connectivity=False)
506            wutils.wait_for_expected_number_of_softap_clients(
507                    self.dut, callbackId, 2)
508
509        # Turn off softap when clients connected
510        wutils.stop_wifi_tethering(self.dut)
511        wutils.wait_for_disconnect(self.dut_client)
512        if len(self.android_devices) > 2:
513            wutils.wait_for_disconnect(self.android_devices[2])
514
515        # Verify client number change back to 0 after softap stop if client
516        # doesn't disconnect before softap stop
517        wutils.wait_for_expected_softap_state(self.dut, callbackId,
518                wifi_constants.WIFI_AP_DISABLING_STATE)
519        wutils.wait_for_expected_softap_state(self.dut, callbackId,
520                wifi_constants.WIFI_AP_DISABLED_STATE)
521        wutils.wait_for_expected_number_of_softap_clients(
522                self.dut, callbackId, 0)
523        # Unregister callback
524        self.dut.droid.unregisterSoftApCallback(callbackId)
525
526        # Check no any callbackId_2 event after unregister
527        asserts.assert_equal(
528                wutils.get_current_number_of_softap_clients(
529                self.dut, callbackId_2), None)
530
531    @test_tracker_info(uuid="35bc4ba1-bade-42ee-a563-0c73afb2402a")
532    def test_softap_auto_shut_off(self):
533        """Test for softap auto shut off
534
535        1. Turn off hotspot
536        2. Register softap callback
537        3. Let client connect to the hotspot
538        4. Start wait [wifi_constants.DEFAULT_SOFTAP_TIMEOUT_S] seconds
539        5. Check hotspot doesn't shut off
540        6. Let client disconnect to the hotspot
541        7. Start wait [wifi_constants.DEFAULT_SOFTAP_TIMEOUT_S] seconds
542        8. Check hotspot auto shut off
543        """
544        config = wutils.start_softap_and_verify(self, WIFI_CONFIG_APBAND_AUTO)
545        # Register callback after softap enabled to avoid unnecessary callback
546        # impact the test
547        callbackId = self.dut.droid.registerSoftApCallback()
548        # Verify clients will update immediately after register callback
549        wutils.wait_for_expected_number_of_softap_clients(self.dut,
550                callbackId, 0)
551        wutils.wait_for_expected_softap_state(self.dut, callbackId,
552                wifi_constants.WIFI_AP_ENABLED_STATE)
553
554        # Force DUTs connect to Network
555        wutils.wifi_connect(self.dut_client, config, check_connectivity=False)
556        wutils.wait_for_expected_number_of_softap_clients(
557                self.dut, callbackId, 1)
558
559        self.dut.log.info("Start waiting %s seconds with 1 clients ",
560                wifi_constants.DEFAULT_SOFTAP_TIMEOUT_S*1.1)
561        time.sleep(wifi_constants.DEFAULT_SOFTAP_TIMEOUT_S*1.1)
562
563        # When client connected, softap should keep as enabled
564        asserts.assert_true(self.dut.droid.wifiIsApEnabled(),
565                "SoftAp is not reported as running")
566
567        wutils.wifi_toggle_state(self.dut_client, False)
568        wutils.wait_for_expected_number_of_softap_clients(self.dut,
569                callbackId, 0)
570        self.dut.log.info("Start waiting %s seconds with 0 client",
571                wifi_constants.DEFAULT_SOFTAP_TIMEOUT_S*1.1)
572        time.sleep(wifi_constants.DEFAULT_SOFTAP_TIMEOUT_S*1.1)
573        # Softap should stop since no client connected
574        # doesn't disconnect before softap stop
575        wutils.wait_for_expected_softap_state(self.dut, callbackId,
576                wifi_constants.WIFI_AP_DISABLING_STATE)
577        wutils.wait_for_expected_softap_state(self.dut, callbackId,
578                wifi_constants.WIFI_AP_DISABLED_STATE)
579        asserts.assert_false(self.dut.droid.wifiIsApEnabled(),
580                "SoftAp is not reported as running")
581        self.dut.droid.unregisterSoftApCallback(callbackId)
582
583    @test_tracker_info(uuid="3a10c7fd-cd8d-4d46-9d12-88a68640e060")
584    def test_softap_auto_shut_off_with_customized_timeout(self):
585        """Test for softap auto shut off
586        1. Turn on hotspot
587        2. Register softap callback
588        3. Backup original shutdown timeout value
589        4. Set up test_shutdown_timeout_value
590        5. Let client connect to the hotspot
591        6. Start wait test_shutdown_timeout_value * 1.1 seconds
592        7. Check hotspot doesn't shut off
593        8. Let client disconnect to the hotspot
594        9. Start wait test_shutdown_timeout_value seconds
595        10. Check hotspot auto shut off
596        """
597        # Backup config
598        original_softap_config = self.dut.droid.wifiGetApConfiguration()
599        # This config only included SSID and Password which used for connection
600        # only.
601        config = wutils.start_softap_and_verify(self, WIFI_CONFIG_APBAND_AUTO)
602
603        # Get current configuration to use for update configuration
604        current_softap_config = self.dut.droid.wifiGetApConfiguration()
605        # Register callback after softap enabled to avoid unnecessary callback
606        # impact the test
607        callbackId = self.dut.droid.registerSoftApCallback()
608        # Verify clients will update immediately after register callback
609        wutils.wait_for_expected_number_of_softap_clients(self.dut,
610                callbackId, 0)
611        wutils.wait_for_expected_softap_state(self.dut, callbackId,
612                wifi_constants.WIFI_AP_ENABLED_STATE)
613
614        # Setup shutdown timeout value
615        test_shutdown_timeout_value_s = 10
616        wutils.save_wifi_soft_ap_config(self.dut, current_softap_config,
617            shutdown_timeout_millis=test_shutdown_timeout_value_s * 1000)
618        # Force DUTs connect to Network
619        wutils.wifi_connect(self.dut_client, config, check_connectivity=False)
620        wutils.wait_for_expected_number_of_softap_clients(
621                self.dut, callbackId, 1)
622
623        self.dut.log.info("Start waiting %s seconds with 1 clients ",
624                test_shutdown_timeout_value_s * 1.1)
625        time.sleep(test_shutdown_timeout_value_s * 1.1)
626
627        # When client connected, softap should keep as enabled
628        asserts.assert_true(self.dut.droid.wifiIsApEnabled(),
629                "SoftAp is not reported as running")
630
631        wutils.wifi_toggle_state(self.dut_client, False)
632        wutils.wait_for_expected_number_of_softap_clients(self.dut,
633                callbackId, 0)
634        self.dut.log.info("Start waiting %s seconds with 0 client",
635                test_shutdown_timeout_value_s * 1.1)
636        time.sleep(test_shutdown_timeout_value_s * 1.1)
637        # Softap should stop since no client connected
638        # doesn't disconnect before softap stop
639        wutils.wait_for_expected_softap_state(self.dut, callbackId,
640                wifi_constants.WIFI_AP_DISABLING_STATE)
641        wutils.wait_for_expected_softap_state(self.dut, callbackId,
642                wifi_constants.WIFI_AP_DISABLED_STATE)
643        asserts.assert_false(self.dut.droid.wifiIsApEnabled(),
644                "SoftAp is not reported as running")
645        self.dut.droid.unregisterSoftApCallback(callbackId)
646
647        # Restore config
648        wutils.save_wifi_soft_ap_config(self.dut, original_softap_config)
649
650    @test_tracker_info(uuid="a9444699-f0d3-4ac3-922b-05e9d4f67968")
651    def test_softap_configuration_update(self):
652      """Test for softap configuration update
653        1. Get current softap configuration
654        2. Update to Open Security configuration
655        3. Update to WPA2_PSK configuration
656        4. Restore the configuration
657      """
658      # Backup config
659      original_softap_config = self.dut.droid.wifiGetApConfiguration()
660      wutils.save_wifi_soft_ap_config(self.dut, {"SSID":"ACTS_TEST"},
661          band=WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, hidden=False,
662          security=WifiEnums.SoftApSecurityType.OPEN, password="",
663          channel=11, max_clients=0, shutdown_timeout_enable=False,
664          shutdown_timeout_millis=0, client_control_enable=True,
665          allowedList=[], blockedList=[])
666
667      wutils.save_wifi_soft_ap_config(self.dut, {"SSID":"ACTS_TEST"},
668          band=WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G, hidden=True,
669          security=WifiEnums.SoftApSecurityType.WPA2, password="12345678",
670          channel=0, max_clients=1, shutdown_timeout_enable=True,
671          shutdown_timeout_millis=10000, client_control_enable=False,
672          allowedList=["aa:bb:cc:dd:ee:ff"], blockedList=["11:22:33:44:55:66"])
673
674      # Restore config
675      wutils.save_wifi_soft_ap_config(self.dut, original_softap_config)
676
677    @test_tracker_info(uuid="8a5d81fa-649c-4679-a823-5cef50828a94")
678    def test_softap_client_control(self):
679        """Test Client Control feature
680        1. Check SoftApCapability to make sure feature is supported
681        2. Backup config
682        3. Setup configuration which used to start softap
683        4. Register callback after softap enabled
684        5. Trigger client connect to softap
685        6. Verify blocking event
686        7. Add client into allowed list
687        8. Verify client connected
688        9. Restore Config
689        """
690        # Register callback to check capability first
691        callbackId = self.dut.droid.registerSoftApCallback()
692        # Check capability first to make sure DUT support this test.
693        capabilityEventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
694            callbackId) + wifi_constants.SOFTAP_CAPABILITY_CHANGED
695        capability = self.dut.ed.pop_event(capabilityEventStr, 10)
696        asserts.skip_if(not capability['data'][wifi_constants
697            .SOFTAP_CAPABILITY_FEATURE_CLIENT_CONTROL],
698            "Client control isn't supported, ignore test")
699
700        # Unregister callback before start test to avoid
701        # unnecessary callback impact the test
702        self.dut.droid.unregisterSoftApCallback(callbackId)
703
704        # start the test
705
706        # Backup config
707        original_softap_config = self.dut.droid.wifiGetApConfiguration()
708        # Setup configuration which used to start softap
709        wutils.save_wifi_soft_ap_config(self.dut, {"SSID":"ACTS_TEST"},
710            band=WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G, hidden=False,
711            security=WifiEnums.SoftApSecurityType.WPA2, password="12345678",
712            client_control_enable=True)
713
714        wutils.start_wifi_tethering_saved_config(self.dut)
715        current_softap_config = self.dut.droid.wifiGetApConfiguration()
716        # Register callback after softap enabled to avoid unnecessary callback
717        # impact the test
718        callbackId = self.dut.droid.registerSoftApCallback()
719
720        # Verify clients will update immediately after register callback
721        wutils.wait_for_expected_number_of_softap_clients(self.dut,
722                callbackId, 0)
723        wutils.wait_for_expected_softap_state(self.dut, callbackId,
724                wifi_constants.WIFI_AP_ENABLED_STATE)
725
726        # Trigger client connection
727        self.dut_client.droid.wifiConnectByConfig(current_softap_config)
728
729        eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
730            callbackId) + wifi_constants.SOFTAP_BLOCKING_CLIENT_CONNECTING
731        blockedClient = self.dut.ed.pop_event(eventStr, 10)
732        asserts.assert_equal(blockedClient['data'][wifi_constants.
733            SOFTAP_BLOCKING_CLIENT_REASON_KEY],
734            wifi_constants.SAP_CLIENT_BLOCK_REASON_CODE_BLOCKED_BY_USER,
735            "Blocked reason code doesn't match")
736
737        # Update configuration, add client into allowed list
738        wutils.save_wifi_soft_ap_config(self.dut, current_softap_config,
739            allowedList=[blockedClient['data'][wifi_constants.
740            SOFTAP_BLOCKING_CLIENT_WIFICLIENT_KEY]])
741
742        # Wait configuration updated
743        time.sleep(3)
744        # Trigger connection again
745        self.dut_client.droid.wifiConnectByConfig(current_softap_config)
746
747        # Verify client connected
748        wutils.wait_for_expected_number_of_softap_clients(self.dut,
749                callbackId, 1)
750
751        # Restore config
752        wutils.save_wifi_soft_ap_config(self.dut, original_softap_config)
753
754        # Unregister callback
755        self.dut.droid.unregisterSoftApCallback(callbackId)
756
757    @test_tracker_info(uuid="d0b61b58-fa2b-4ced-bc52-3366cb826e79")
758    def test_softap_max_client_setting(self):
759        """Test Client Control feature
760        1. Check device number and capability to make sure feature is supported
761        2. Backup config
762        3. Setup configuration which used to start softap
763        4. Register callback after softap enabled
764        5. Trigger client connect to softap
765        6. Verify blocking event
766        7. Extend max client setting
767        8. Verify client connected
768        9. Restore Config
769        """
770        asserts.skip_if(len(self.android_devices) < 3,
771                        "Device less than 3, skip the test.")
772        # Register callback to check capability first
773        callbackId = self.dut.droid.registerSoftApCallback()
774        # Check capability first to make sure DUT support this test.
775        capabilityEventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
776            callbackId) + wifi_constants.SOFTAP_CAPABILITY_CHANGED
777        capability = self.dut.ed.pop_event(capabilityEventStr, 10)
778        asserts.skip_if(not capability['data'][wifi_constants
779            .SOFTAP_CAPABILITY_FEATURE_CLIENT_CONTROL],
780            "Client control isn't supported, ignore test")
781
782        # Unregister callback before start test to avoid
783        # unnecessary callback impact the test
784        self.dut.droid.unregisterSoftApCallback(callbackId)
785
786        # Backup config
787        original_softap_config = self.dut.droid.wifiGetApConfiguration()
788        # Setup configuration which used to start softap
789        wutils.save_wifi_soft_ap_config(self.dut, {"SSID":"ACTS_TEST"},
790            band=WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G, hidden=False,
791            security=WifiEnums.SoftApSecurityType.WPA2, password="12345678",
792            max_clients=1)
793
794        wutils.start_wifi_tethering_saved_config(self.dut)
795        current_softap_config = self.dut.droid.wifiGetApConfiguration()
796        # Register callback again after softap enabled to avoid
797        # unnecessary callback impact the test
798        callbackId = self.dut.droid.registerSoftApCallback()
799
800        # Verify clients will update immediately after register calliback
801        wutils.wait_for_expected_number_of_softap_clients(self.dut,
802                callbackId, 0)
803        wutils.wait_for_expected_softap_state(self.dut, callbackId,
804                wifi_constants.WIFI_AP_ENABLED_STATE)
805
806        # Trigger client connection
807        self.dut_client.droid.wifiConnectByConfig(current_softap_config)
808        self.dut_client_2.droid.wifiConnectByConfig(current_softap_config)
809        # Wait client connect
810        time.sleep(3)
811
812        # Verify one client connected and one blocked due to max client
813        eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
814            callbackId) + wifi_constants.SOFTAP_BLOCKING_CLIENT_CONNECTING
815        blockedClient = self.dut.ed.pop_event(eventStr, 10)
816        asserts.assert_equal(blockedClient['data'][wifi_constants.
817            SOFTAP_BLOCKING_CLIENT_REASON_KEY],
818            wifi_constants.SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS,
819            "Blocked reason code doesn't match")
820        wutils.wait_for_expected_number_of_softap_clients(self.dut,
821                callbackId, 1)
822
823        # Update configuration, extend client to 2
824        wutils.save_wifi_soft_ap_config(self.dut, current_softap_config,
825            max_clients=2)
826
827        # Wait configuration updated
828        time.sleep(3)
829        # Trigger connection again
830        self.dut_client_2.droid.wifiConnectByConfig(current_softap_config)
831        # Wait client connect
832        time.sleep(3)
833        # Verify client connected
834        wutils.wait_for_expected_number_of_softap_clients(self.dut,
835                callbackId, 2)
836
837        # Restore config
838        wutils.save_wifi_soft_ap_config(self.dut, original_softap_config)
839
840        # Unregister callback
841        self.dut.droid.unregisterSoftApCallback(callbackId)
842
843    @test_tracker_info(uuid="07b4e5b3-48ce-49b9-a83e-3e288bb88e91")
844    def test_softap_5g_preferred_country_code_de(self):
845        """Verify softap works when set to 5G preferred band
846           with country code 'DE'.
847
848        Steps:
849            1. Set country code to Germany
850            2. Save a softap configuration set to 5G preferred band.
851            3. Start softap and verify it works
852            4. Verify a client device can connect to it.
853        """
854        wutils.set_wifi_country_code(
855            self.dut, wutils.WifiEnums.CountryCode.GERMANY)
856        sap_config = self.create_softap_config()
857        wifi_network = sap_config.copy()
858        sap_config[
859            WifiEnums.AP_BAND_KEY] = WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G
860        sap_config[WifiEnums.SECURITY] = WifiEnums.SoftApSecurityType.WPA2
861        asserts.assert_true(
862            self.dut.droid.wifiSetWifiApConfiguration(sap_config),
863            "Failed to set WifiAp Configuration")
864        wutils.start_wifi_tethering_saved_config(self.dut)
865        softap_conf = self.dut.droid.wifiGetApConfiguration()
866        self.log.info("softap conf: %s" % softap_conf)
867        sap_band = softap_conf[WifiEnums.AP_BAND_KEY]
868        asserts.assert_true(
869            sap_band == WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G,
870            "Soft AP didn't start in 5G preferred band")
871        wutils.connect_to_wifi_network(self.dut_client, wifi_network)
872
873    """ Tests End """
874
875
876if __name__ == "__main__":
877    pass
878