def enable_wifi_hotspot(self):
     """Enable wifi hotspot."""
     sap_config = wutils.create_softap_config()
     wutils.start_wifi_tethering(self.dut,
                                 sap_config[wutils.WifiEnums.SSID_KEY],
                                 sap_config[wutils.WifiEnums.PWD_KEY],
                                 wutils.WifiEnums.WIFI_CONFIG_APBAND_2G)
    def test_tether_startup_while_connected_to_a_network(self):
        """Test full startup of wifi tethering in auto-band while the device
        is connected to a network.

        1. Connect to an open network.
        2. Turn on AP mode (in auto band).
        3. Verify SoftAP active.
        4. Make a client connect to the AP.
        5. Shutdown wifi tethering.
        6. Ensure that the client disconnected.
        """
        wutils.wifi_toggle_state(self.dut, True)
        wutils.wifi_connect(self.dut, self.open_network)
        config = self.create_softap_config()
        wutils.start_wifi_tethering(self.dut,
                                    config[wutils.WifiEnums.SSID_KEY],
                                    config[wutils.WifiEnums.PWD_KEY],
                                    WIFI_CONFIG_APBAND_AUTO)
        asserts.assert_true(self.dut.droid.wifiIsApEnabled(),
                            "SoftAp is not reported as running")
        # local hotspot may not have internet connectivity
        self.confirm_softap_in_scan_results(config[wutils.WifiEnums.SSID_KEY])
        wutils.wifi_connect(self.dut_client, config, check_connectivity=False)
        wutils.stop_wifi_tethering(self.dut)
        wutils.wait_for_disconnect(self.dut_client)
    def run_incompat_service_then_aware(self, is_p2p):
        """Validate that if an Aware-incompatible service is already up then any
    Aware operation fails"""
        dut = self.android_devices[0]

        # start other service
        if is_p2p:
            dut.droid.wifiP2pInitialize()
        else:
            wutils.start_wifi_tethering(dut, self.TETHER_SSID, password=None)

        # expect an announcement about Aware non-availability
        autils.wait_for_event(dut, aconsts.BROADCAST_WIFI_AWARE_NOT_AVAILABLE)

        # try starting anyway (expect failure)
        dut.droid.wifiAwareAttach()
        autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACH_FAILED)

        # stop other service
        if is_p2p:
            dut.droid.wifiP2pClose()
        else:
            wutils.stop_wifi_tethering(dut)

        # expect an announcement about Aware availability
        autils.wait_for_event(dut, aconsts.BROADCAST_WIFI_AWARE_AVAILABLE)

        # try starting Aware
        dut.droid.wifiAwareAttach()
        autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED)
示例#4
0
    def test_randomized_mac_used_during_connection(self):
        """Verify that the randomized MAC address and not the factory
        MAC address is used during connection by checking the softap logs.

        Steps:
        1. Set up softAP on dut_softap.
        2. Have dut connect to the softAp.
        3. Verify that only randomized MAC appears in softAp logs.
        """
        self.dut_softap.adb.shell(LOG_CLEAR)
        config = wutils.create_softap_config()
        wutils.start_wifi_tethering(self.dut_softap,
                                    config[wutils.WifiEnums.SSID_KEY],
                                    config[wutils.WifiEnums.PWD_KEY],
                                    WIFI_CONFIG_APBAND_2G)

        # Internet validation fails when dut_softap does not have a valid sim
        # supporting softap. Since this test is not checking for internet
        # validation, we suppress failure signals.
        wutils.connect_to_wifi_network(self.dut, config, assert_on_fail=False)
        mac = self.get_current_mac_address(self.dut)
        wutils.stop_wifi_tethering(self.dut_softap)

        self.is_valid_randomized_mac_address(mac)
        log = self.dut_softap.adb.shell(LOG_GREP.format(mac))
        asserts.assert_true(len(log) > 0, "Randomized MAC not in log.")
        log = self.dut_softap.adb.shell(LOG_GREP.format(self.dut_factory_mac))
        asserts.assert_true(len(log) == 0, "Factory MAC is in log.")
    def test_ipv6_tethering(self):
        """ IPv6 tethering test

        Steps:
            1. Start wifi tethering on provider
            2. Client connects to wifi tethering SSID
            3. Verify IPv6 address on the client's link properties
            4. Verify ping on client using ping6 which should pass
            5. Disable mobile data on provider and verify that link properties
               does not have IPv6 address and default route
        """
        # Start wifi tethering on the hotspot device
        self.log.info("Start tethering on provider: {}".format(
            self.hotspot_device.serial))
        wifi_test_utils.start_wifi_tethering(self.hotspot_device, self.ssid,
                                             self.password)
        time.sleep(tel_defines.WAIT_TIME_ANDROID_STATE_SETTLING)
        asserts.assert_true(
            tel_data_utils.verify_http_connection(self.log,
                                                  self.hotspot_device),
            "Could not verify http connection on the provider")

        # Verify link properties on hotspot device
        self.log.info("Check IPv6 properties on the hotspot device")
        self._verify_ipv6_tethering(self.hotspot_device)

        # Connect the client to the SSID
        asserts.assert_true(
            tel_test_utils.WifiUtils.wifi_connect(self.log,
                                                  self.tethered_device,
                                                  self.ssid, self.password),
            "Unable to connect to the hotspot SSID")

        # Need to wait atleast 2 seconds for IPv6 address to
        # show up in the link properties
        time.sleep(2)

        # Verify link properties on tethered device
        self.log.info("Check IPv6 properties on the tethered device")
        self._verify_ipv6_tethering(self.tethered_device)

        # Verify ping6 on tethered device
        ping_result = self.tethered_device.droid.pingHost(
            "www.google.com", 5, "ping6")
        if self._supports_ipv6_tethering(self.hotspot_device):
            asserts.assert_true(ping_result, "Ping6 failed on the client")
        else:
            asserts.assert_true(not ping_result, "Ping6 failed as expected")

        # Disable mobile data on hotspot device
        # and verify the link properties on tethered device
        self.log.info("Disabling mobile data on hotspot device")
        self.hotspot_device.droid.telephonyToggleDataConnection(False)
        asserts.assert_equal(
            self.hotspot_device.droid.telephonyGetDataConnectionState(),
            tel_defines.DATA_STATE_CONNECTED, "Could not disable cell data")
        time.sleep(2)  # wait until the IPv6 is removed from link properties
        asserts.assert_true(
            not self._find_ipv6_default_route(self.tethered_device),
            "Found IPv6 default route in link properties - Data off")
    def run_aware_then_incompat_service(self, is_p2p):
        """Run test to validate that a running Aware session terminates when an
    Aware-incompatible service is started.

    Args:
      is_p2p: True for p2p, False for SoftAP
    """
        dut = self.android_devices[0]

        # start Aware
        id = dut.droid.wifiAwareAttach()
        autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED)

        # start other service
        if is_p2p:
            dut.droid.wifiP2pInitialize()
        else:
            wutils.start_wifi_tethering(dut, self.TETHER_SSID, password=None)

        # expect an announcement about Aware non-availability
        autils.wait_for_event(dut, aconsts.BROADCAST_WIFI_AWARE_NOT_AVAILABLE)

        # local clean-up
        if not is_p2p:
            wutils.stop_wifi_tethering(dut)
示例#7
0
    def _start_wifi_tethering(self, wifi_band):
        """ Start wifi tethering on hotspot device

            Args:
              1. wifi_band: specifies the wifi band to start the hotspot
              on. The current options are 2G and 5G
        """
        wutils.start_wifi_tethering(self.hotspot_device, self.ssid,
                                    self.password, wifi_band)
示例#8
0
    def sap_rvr_test_func(self):
        """Main function to test Soft AP RvR.

        The function sets up the phones in the correct soft ap and client mode
        configuration and calls run_rvr to sweep attenuation and measure
        throughput

        Args:
            channel: Specifies AP's channel
            mode: Specifies AP's bandwidth/mode (11g, VHT20, VHT40, VHT80)
        Returns:
            rvr_result: dict containing rvr_results and meta data
        """
        #Initialize RvR test parameters
        num_atten_steps = int((self.test_params["rvr_atten_stop"] -
                               self.test_params["rvr_atten_start"]) /
                              self.test_params["rvr_atten_step"])
        self.rvr_atten_range = [
            self.test_params["rvr_atten_start"] +
            x * self.test_params["rvr_atten_step"]
            for x in range(0, num_atten_steps)
        ]
        rvr_result = {}
        # Reset WiFi on all devices
        for dev in self.android_devices:
            wutils.reset_wifi(dev)
            dev.droid.wifiSetCountryCode(wutils.WifiEnums.CountryCode.US)
        # Setup Soft AP
        sap_config = wutils.create_softap_config()
        wutils.start_wifi_tethering(self.android_devices[0],
                                    sap_config[wutils.WifiEnums.SSID_KEY],
                                    sap_config[wutils.WifiEnums.PWD_KEY],
                                    self.sap_band_enum)
        self.main_network = {
            "SSID": sap_config[wutils.WifiEnums.SSID_KEY],
            "password": sap_config[wutils.WifiEnums.PWD_KEY]
        }
        # Set attenuator to 0 dB
        [self.attenuators[i].set_atten(0) for i in range(self.num_atten)]
        # Connect DUT to Network
        wutils.wifi_connect(self.android_devices[1],
                            self.main_network,
                            num_of_tries=5,
                            assert_on_fail=False)
        connection_info = self.get_sap_connection_info()
        self.test_params["iperf_server_address"] = connection_info[
            "ap_ip_address"]
        # Run RvR and log result
        rvr_result["test_name"] = self.current_test_name
        rvr_result["attenuation"] = list(self.rvr_atten_range)
        rvr_result["fixed_attenuation"] = self.test_params[
            "fixed_attenuation"][str(connection_info["channel"])]
        rvr_result["throughput_receive"] = self.rvr_test()
        self.testclass_results.append(rvr_result)
        wutils.stop_wifi_tethering(self.android_devices[0])
        return rvr_result
    def test_firmware_crash_softap_reconnect_stress(self):
        """Firmware crash stress test for softap mode

        1. Turn off dut's Wi-Fi
        2. Turn on dut's hotspot and connected by dut client
        3. Trigger firmware crash
        4. Check ssr happened
        5. Check the connectivity of hotspot's client
        6. Repeat step 3~5
        """
        wutils.wifi_toggle_state(self.dut, False)
        # Setup Soft AP
        sap_config = wutils.create_softap_config()
        wutils.start_wifi_tethering(self.dut,
                                    sap_config[wutils.WifiEnums.SSID_KEY],
                                    sap_config[wutils.WifiEnums.PWD_KEY],
                                    wutils.WifiEnums.WIFI_CONFIG_APBAND_2G)
        config = {
            "SSID": sap_config[wutils.WifiEnums.SSID_KEY],
            "password": sap_config[wutils.WifiEnums.PWD_KEY]
        }
        # DUT client connects to softap
        wutils.wifi_toggle_state(self.dut_client, True)
        wutils.connect_to_wifi_network(self.dut_client,
                                       config,
                                       check_connectivity=False)
        # Ping the DUT
        dut_addr = self.dut.droid.connectivityGetIPv4Addresses(
            self.ap_iface)[0]
        asserts.assert_true(
            utils.adb_shell_ping(self.dut_client,
                                 count=10,
                                 dest_ip=dut_addr,
                                 timeout=20),
            "%s ping %s failed" % (self.dut_client.serial, dut_addr))
        for count in range(self.stress_count):
            self.log.info(
                "%s: %d/%d" %
                (self.current_test_name, count + 1, self.stress_count))
            wutils.reset_wifi(self.dut_client)
            # Trigger firmware crash
            self.trigger_wifi_firmware_crash(self.dut)
            # Connect DUT to Network
            wutils.connect_to_wifi_network(self.dut_client,
                                           config,
                                           check_connectivity=False)
            # Ping the DUT
            server_addr = self.dut.droid.connectivityGetIPv4Addresses(
                self.ap_iface)[0]
            asserts.assert_true(
                utils.adb_shell_ping(self.dut_client,
                                     count=10,
                                     dest_ip=server_addr,
                                     timeout=20),
                "%s ping %s failed" % (self.dut_client.serial, server_addr))
        wutils.stop_wifi_tethering(self.dut)
    def start_softap_and_verify(self, band):
        """Test startup of softap

        1. Brinup AP mode.
        2. Verify SoftAP active using the client device.
        """
        config = self.create_softap_config()
        wutils.start_wifi_tethering(self.dut,
                                    config[wutils.WifiEnums.SSID_KEY],
                                    config[wutils.WifiEnums.PWD_KEY], band)
        self.confirm_softap_in_scan_results(config[wutils.WifiEnums.SSID_KEY])
示例#11
0
    def _start_wifi_tethering(self, wifi_band=WIFI_CONFIG_APBAND_2G):
        """ Start wifi tethering on hotspot device

        Args:
            1. wifi_band: specifies the wifi band to start the hotspot
               on. The current options are 2G and 5G
        """
        wutils.start_wifi_tethering(self.hotspot_device,
                                    self.network[wutils.WifiEnums.SSID_KEY],
                                    self.network[wutils.WifiEnums.PWD_KEY],
                                    wifi_band)
示例#12
0
    def test_wifi_tethering_open_network_5g(self):
        """ Steps:

            1. Start wifi tethering with open network 5G band
               (Not allowed manually. b/72412729)
            2. Connect tethered device to the SSID
            3. Verify internet connectivity
        """
        wutils.start_wifi_tethering(
            self.hotspot_device, self.open_network[wutils.WifiEnums.SSID_KEY],
            None, WIFI_CONFIG_APBAND_5G)
        wutils.wifi_connect(self.tethered_devices[0], self.open_network)
        wutils.stop_wifi_tethering(self.hotspot_device)
    def validate_full_tether_startup(self,
                                     band=None,
                                     hidden=None,
                                     test_ping=False,
                                     test_clients=None):
        """Test full startup of wifi tethering

        1. Report current state.
        2. Switch to AP mode.
        3. verify SoftAP active.
        4. Shutdown wifi tethering.
        5. verify back to previous mode.
        """
        initial_wifi_state = self.dut.droid.wifiCheckState()
        initial_cell_state = tel_utils.is_sim_ready(self.log, self.dut)
        self.dut.log.info("current state: %s", initial_wifi_state)
        self.dut.log.info("is sim ready? %s", initial_cell_state)
        if initial_cell_state:
            self.check_cell_data_and_enable()
        config = self.create_softap_config()
        wutils.start_wifi_tethering(self.dut,
                                    config[wutils.WifiEnums.SSID_KEY],
                                    config[wutils.WifiEnums.PWD_KEY], band,
                                    hidden)
        if hidden:
            # First ensure it's not seen in scan results.
            self.confirm_softap_not_in_scan_results(
                config[wutils.WifiEnums.SSID_KEY])
            # If the network is hidden, it should be saved on the client to be
            # seen in scan results.
            config[wutils.WifiEnums.HIDDEN_KEY] = True
            ret = self.dut_client.droid.wifiAddNetwork(config)
            asserts.assert_true(ret != -1, "Add network %r failed" % config)
            self.dut_client.droid.wifiEnableNetwork(ret, 0)
        self.confirm_softap_in_scan_results(config[wutils.WifiEnums.SSID_KEY])
        if test_ping:
            self.validate_ping_between_softap_and_client(config)
        if test_clients:
            if hasattr(self, 'arduino_wifi_dongles'):
                self.validate_traffic_between_softap_clients(config)
            if len(self.android_devices) > 2:
                self.validate_ping_between_two_clients(config)
        wutils.stop_wifi_tethering(self.dut)
        asserts.assert_false(self.dut.droid.wifiIsApEnabled(),
                             "SoftAp is still reported as running")
        if initial_wifi_state:
            wutils.wait_for_wifi_state(self.dut, True)
        elif self.dut.droid.wifiCheckState():
            asserts.fail(
                "Wifi was disabled before softap and now it is enabled")
    def test_full_tether_startup(self):
        """Test full startup of wifi tethering

        1. Report current state.
        2. Switch to AP mode.
        3. verify SoftAP active.
        4. Shutdown wifi tethering.
        5. verify back to previous mode.
        """
        success = True
        initial_wifi_state = self.dut.droid.wifiCheckState()
        initial_cell_state = is_sim_ready(self.log, self.dut)
        self.log.info("current state: %s", initial_wifi_state)
        self.log.info("is sim ready? %s", initial_cell_state)

        if initial_cell_state:
            self.check_cell_data_and_enable()

        config = self.create_softap_config()

        success = wutils.start_wifi_tethering(self.dut,
                                              config[wutils.WifiEnums.SSID_KEY],
                                              config[wutils.WifiEnums.PWD_KEY])
        asserts.assert_true(success, "call to start_wifi_tethering returned false.  Check config")
        self.confirm_softap_in_scan_results(config[wutils.WifiEnums.SSID_KEY])
        wutils.stop_wifi_tethering(self.dut)
        asserts.assert_true(not self.dut.droid.wifiIsApEnabled(),
                            "SoftAp is still reported as running")
        if initial_wifi_state:
            self.verify_return_to_wifi_enabled()
        elif not self.dut.droid.wifiCheckState():
            asserts.fail("Wifi was disabled before softap and now it is enabled")
示例#15
0
    def start_softap_and_verify(self, band):
        """Bring-up softap and verify AP mode and in scan results.

        Args:
            band: The band to use for softAP.

        """
        config = wutils.create_softap_config()
        wutils.start_wifi_tethering(self.dut,
                                    config[wutils.WifiEnums.SSID_KEY],
                                    config[wutils.WifiEnums.PWD_KEY], band=band)
        asserts.assert_true(self.dut.droid.wifiIsApEnabled(),
                             "SoftAp is not reported as running")
        wutils.start_wifi_connection_scan_and_ensure_network_found(
            self.dut_client, config[wutils.WifiEnums.SSID_KEY])
        return config
示例#16
0
    def setup_sap_rvr_test(self, testcase_params):
        """Function that gets devices ready for the test.

        Args:
            testcase_params: dict containing test-specific parameters
        """
        for dev in self.android_devices:
            if not wputils.health_check(dev, 20):
                asserts.skip('DUT health check failed. Skipping test.')
        # Reset WiFi on all devices
        for dev in self.android_devices:
            self.dut.go_to_sleep()
            wutils.reset_wifi(dev)
            wutils.set_wifi_country_code(dev, wutils.WifiEnums.CountryCode.US)

        # Setup Soft AP
        sap_config = wutils.create_softap_config()
        self.log.info('SoftAP Config: {}'.format(sap_config))
        wutils.start_wifi_tethering(self.android_devices[0],
                                    sap_config[wutils.WifiEnums.SSID_KEY],
                                    sap_config[wutils.WifiEnums.PWD_KEY],
                                    testcase_params['sap_band_enum'])
        # Set attenuator to 0 dB
        for attenuator in self.attenuators:
            attenuator.set_atten(0, strict=False)
        # Connect DUT to Network
        testcase_params['test_network'] = {
            'SSID': sap_config[wutils.WifiEnums.SSID_KEY],
            'password': sap_config[wutils.WifiEnums.PWD_KEY]
        }
        wutils.wifi_connect(self.android_devices[1],
                            testcase_params['test_network'],
                            num_of_tries=5,
                            check_connectivity=False)
        # Compile meta data
        self.access_point = AccessPointTuple(sap_config)
        testcase_params['connection_info'] = self.get_sap_connection_info()
        testcase_params['channel'] = testcase_params['connection_info'][
            'channel']
        testcase_params['test_network']['channel'] = testcase_params[
            'connection_info']['channel']
        if testcase_params['channel'] < 13:
            testcase_params['mode'] = 'VHT20'
        else:
            testcase_params['mode'] = 'VHT80'
        testcase_params['iperf_server_address'] = testcase_params[
            'connection_info']['ap_ip_address']
示例#17
0
    def test_wifi_tethering_data_usage_limit_downlink(self):
        """ Verify connectivity when data usage limit reached

        Steps:
            1. Set the data usage limit to current data usage + 10MB
            2. Start wifi tethering and connect a dut to the SSID
            3. Download 20MB data on tethered device
            4. File download stops and data limit reached
            5. Verify data usage limit
        """
        # connect device to wifi hotspot
        ad = self.tethered_devices[0]
        wutils.toggle_wifi_off_and_on(self.dut)
        wutils.start_wifi_tethering(self.dut,
                                    self.network[wutils.WifiEnums.SSID_KEY],
                                    self.network[wutils.WifiEnums.PWD_KEY],
                                    ttutils.WIFI_CONFIG_APBAND_2G)
        wutils.wifi_connect(ad, self.network)

        # get pre mobile data usage
        total_pre = self._get_total_data_usage_for_device(cconst.TYPE_MOBILE)

        # set data usage limit to current usage limit + 10MB
        self.log.info("Setting data usage limit to %sMB" %
                      (total_pre + INC_DATA))
        self.dut.droid.connectivitySetDataUsageLimit(
            self.sub_id, str(int((total_pre + INC_DATA) * BYTE_TO_MB_ANDROID)))

        # download file from tethered device
        http_file_download_by_chrome(ad,
                                     self.download_file,
                                     self.file_size,
                                     timeout=120)
        total_pst = self._get_total_data_usage_for_device(cconst.TYPE_MOBILE)

        # verify data usage
        connectivity_status = wutils.validate_connection(ad)
        self.dut.droid.connectivityFactoryResetNetworkPolicies(self.sub_id)
        wutils.stop_wifi_tethering(self.dut)
        self.log.info("Expected data usage: %s" % (total_pre + INC_DATA))
        self.log.info("Actual data usage: %s" % total_pst)
        asserts.assert_true(
            not connectivity_status,
            "Device has internet connectivity after reaching data limit")
        return total_pst - total_pre - INC_DATA < DATA_USG_ERR
示例#18
0
    def test_stress_softAP_startup_and_stop_5g(self):
        """Test to bring up softAP and down for N times.

        Steps:
            1. Bring up softAP on 5G.
            2. Check for softAP on teh client device.
            3. Turn ON WiFi.
            4. Verify softAP is turned down and WiFi is up.

        """
        ap_ssid = "softap_" + utils.rand_ascii_str(8)
        ap_password = utils.rand_ascii_str(8)
        self.dut.log.info("softap setup: %s %s", ap_ssid, ap_password)
        config = {wutils.WifiEnums.SSID_KEY: ap_ssid}
        config[wutils.WifiEnums.PWD_KEY] = ap_password
        # Set country code explicitly to "US".
        wutils.set_wifi_country_code(self.dut, wutils.WifiEnums.CountryCode.US)
        wutils.set_wifi_country_code(self.dut_client,
                                     wutils.WifiEnums.CountryCode.US)
        for count in range(self.stress_count):
            initial_wifi_state = self.dut.droid.wifiCheckState()
            wutils.start_wifi_tethering(self.dut, ap_ssid, ap_password,
                                        WifiEnums.WIFI_CONFIG_APBAND_5G)
            wutils.start_wifi_connection_scan_and_ensure_network_found(
                self.dut_client, ap_ssid)
            wutils.stop_wifi_tethering(self.dut)
            asserts.assert_false(self.dut.droid.wifiIsApEnabled(),
                                 "SoftAp failed to shutdown!")
            # Give some time for WiFi to come back to previous state.
            time.sleep(2)
            cur_wifi_state = self.dut.droid.wifiCheckState()
            if initial_wifi_state != cur_wifi_state:
                raise signals.TestFailure(
                    "Wifi state was %d before softAP and %d now!" %
                    (initial_wifi_state, cur_wifi_state),
                    extras={
                        "Iterations": "%d" % self.stress_count,
                        "Pass": "******" % count
                    })
        raise signals.TestPass(details="",
                               extras={
                                   "Iterations": "%d" % self.stress_count,
                                   "Pass": "******" % (count + 1)
                               })
示例#19
0
    def setup_hotspot(self, connect_client=False):
        """Configure Hotspot and connects client device.

        Args:
            connect_client: Connects (or not) the client device to the Hotspot
        """
        try:
            if self.test_configs.band == self.PARAM_2G_BAND:
                wifi_band_id = WIFI_CONFIG_APBAND_2G
            elif self.test_configs.band == self.PARAM_5G_BAND:
                wifi_band_id = WIFI_CONFIG_APBAND_5G
            else:
                raise ValueError()
        except ValueError:
            self.log.error(
                "The test name has to include parameter {} followed by "
                "either {} or {}.".format(self.PARAM_WIFI_BAND,
                                          self.PARAM_2G_BAND,
                                          self.PARAM_5G_BAND))
            return False

        # Turn WiFi ON for DUT (hotspot) and connect to AP (WiFiSharing)
        # Hotspot needs airplane mode OFF
        self.dut.droid.connectivityToggleAirplaneMode(False)
        time.sleep(2)
        if self.test_configs.wifi_sharing == 'OFF':
            wutils.wifi_toggle_state(self.dut, True)
            time.sleep(2)
        else:
            self.setup_ap_connection(
                self.main_network[self.test_configs.wifi_sharing])

        # Setup tethering on dut
        wutils.start_wifi_tethering(self.dut,
                                    self.network[wutils.WifiEnums.SSID_KEY],
                                    self.network[wutils.WifiEnums.PWD_KEY],
                                    wifi_band_id)

        # Connect client device to Hotspot
        if connect_client:
            wutils.wifi_connect(self.android_devices[1],
                                self.network,
                                check_connectivity=False)
    def power_tel_tethering_test(self):
        """ Measure power and throughput during data transmission.

        Starts WiFi tethering in the DUT and connects a second device. Then
        the iPerf client is hosted in the second android device.

        """
        # Country Code set to 00 after toggling airplane mode.
        # We need to set this right before we setup a hotspot
        # Set country codes on both devices to US to connect to 5GHz
        country_code = "US"
        hotspot_dut = self.dut
        slave_dut = self.android_devices[1]
        for dut in [hotspot_dut, slave_dut]:
            self.log.info("Setting Country Code to %s for SN:%s" %
                          (country_code, dut.serial))
            wutils.set_wifi_country_code(dut, country_code)

        # Setup tethering
        wutils.start_wifi_tethering(self.dut,
                                    self.network[wutils.WifiEnums.SSID_KEY],
                                    self.network[wutils.WifiEnums.PWD_KEY],
                                    self.wifi_band)

        wutils.wifi_connect(self.android_devices[1],
                            self.network,
                            check_connectivity=False)

        # Start data traffic
        iperf_helpers = self.start_tel_traffic(self.android_devices[1])

        # Measure power
        result = self.collect_power_data()

        # Wait for iPerf to finish
        time.sleep(self.IPERF_MARGIN + 2)

        # Collect throughput measurement
        self.iperf_results = self.get_iperf_results(self.android_devices[1],
                                                    iperf_helpers)

        # Checks if power is below the required threshold.
        self.pass_fail_check(result.average_current)
    def test_firmware_crash_concurrent_reconnect_stress(self):
        """Firmware crash stress test for concurrent mode

        1. Turn on dut's Wi-Fi and connect to access point
        2. Turn on dut's hotspot and connected by dut client
        3. Trigger firmware crash
        4. Check ssr happened
        5. Check dut can connect to access point
        6. Check the connectivity of hotspot's client
        7. Repeat step 3~6
        """
        if self.dut.model not in self.dbs_supported_models:
            raise signals.TestSkip("%s does not support dual interfaces" %
                                   self.dut.model)

        # Connect DUT to Network
        wutils.wifi_toggle_state(self.dut, True)
        wutils.connect_to_wifi_network(self.dut, self.network)
        # Setup Soft AP
        sap_config = wutils.create_softap_config()
        wutils.start_wifi_tethering(self.dut,
                                    sap_config[wutils.WifiEnums.SSID_KEY],
                                    sap_config[wutils.WifiEnums.PWD_KEY],
                                    wutils.WifiEnums.WIFI_CONFIG_APBAND_2G)
        config = {
            "SSID": sap_config[wutils.WifiEnums.SSID_KEY],
            "password": sap_config[wutils.WifiEnums.PWD_KEY]
        }
        # Client connects to Softap
        wutils.wifi_toggle_state(self.dut_client, True)
        wutils.connect_to_wifi_network(self.dut_client, config)
        for count in range(self.stress_count):
            self.log.info(
                "%s: %d/%d" %
                (self.current_test_name, count + 1, self.stress_count))
            wutils.reset_wifi(self.dut_client)
            wutils.reset_wifi(self.dut)
            # Trigger firmware crash
            self.trigger_wifi_firmware_crash(self.dut)
            wutils.connect_to_wifi_network(self.dut, self.network)
            wutils.connect_to_wifi_network(self.dut_client, config)
        wutils.stop_wifi_tethering(self.dut)
示例#22
0
    def start_softap_and_verify(self, band, check_connectivity=True):
        """Test startup of softap.

        1. Bring up AP mode.
        2. Verify SoftAP active using the client device.

        Args:
            band: wifi band to start soft ap on
            check_connectivity: If set, verify internet connectivity

        Returns:
            Softap config
        """
        config = self.create_softap_config()
        wutils.start_wifi_tethering(self.dut, config[WifiEnums.SSID_KEY],
                                    config[WifiEnums.PWD_KEY], band)
        for ad in self.android_devices[1:]:
            wutils.connect_to_wifi_network(
                ad, config, check_connectivity=check_connectivity)
        return config
示例#23
0
    def test_wifi_tethering_mobile_data_usage_downlink(self):
        """ Verify mobile data usage with tethered device

        Steps:
            1. Start wifi hotspot and connect tethered device to it
            2. Get the data usage on hotspot device
            3. Download data on tethered device
            4. Get the new data usage on hotspot device
            5. Verify that hotspot device's data usage increased by downloaded file size
        """
        # connect device to wifi hotspot
        ad = self.tethered_devices[0]
        wutils.start_wifi_tethering(self.dut,
                                    self.network[wutils.WifiEnums.SSID_KEY],
                                    self.network[wutils.WifiEnums.PWD_KEY],
                                    ttutils.WIFI_CONFIG_APBAND_2G)
        wutils.wifi_connect(ad, self.network)

        # get pre mobile data usage
        (aos_pre, app_pre,
         total_pre) = self._get_data_usage(self.dut, cconst.TYPE_MOBILE)

        # download file through app
        self._download_data_through_app(ad)

        # get new mobile data usage
        (aos_pst, app_pst,
         total_pst) = self._get_data_usage(self.dut, cconst.TYPE_MOBILE)

        # stop wifi hotspot
        wutils.stop_wifi_tethering(self.dut)

        # verify data usage
        aos_diff = aos_pst - aos_pre
        app_diff = app_pst - app_pre
        total_diff = total_pst - total_pre
        self.log.info("Data usage of Android os increased by %s" % aos_diff)
        self.log.info("Data usage of ConnUID app increased by %s" % app_diff)
        self.log.info("Data usage on the device increased by %s" % total_diff)
        return (aos_diff < DATA_ERR) and (app_diff < DATA_ERR) and \
            (self.file_size < total_diff < self.file_size + DATA_USG_ERR)
示例#24
0
    def test_stress_softAP_startup_and_stop_5g(self):
        """Test to bring up softAP and down for N times.

        Steps:
            1. Bring up softAP on 5G.
            2. Check for softAP on teh client device.
            3. Turn ON WiFi.
            4. Verify softAP is turned down and WiFi is up.

        """
        ap_ssid = "softap_" + utils.rand_ascii_str(8)
        ap_password = utils.rand_ascii_str(8)
        self.dut.log.info("softap setup: %s %s", ap_ssid, ap_password)
        config = {wutils.WifiEnums.SSID_KEY: ap_ssid}
        config[wutils.WifiEnums.PWD_KEY] = ap_password
        # Set country code explicitly to "US".
        self.dut.droid.wifiSetCountryCode(wutils.WifiEnums.CountryCode.US)
        self.dut_client.droid.wifiSetCountryCode(
            wutils.WifiEnums.CountryCode.US)
        for count in range(self.stress_count):
            initial_wifi_state = self.dut.droid.wifiCheckState()
            wutils.start_wifi_tethering(self.dut, ap_ssid, ap_password,
                                        WifiEnums.WIFI_CONFIG_APBAND_5G)
            wutils.start_wifi_connection_scan_and_ensure_network_found(
                self.dut_client, ap_ssid)
            # Toggle WiFi ON, which inturn calls softAP teardown.
            wutils.wifi_toggle_state(self.dut, True)
            time.sleep(TIMEOUT)
            asserts.assert_false(self.dut.droid.wifiIsApEnabled(),
                                 "SoftAp failed to shutdown!")
            time.sleep(TIMEOUT)
            cur_wifi_state = self.dut.droid.wifiCheckState()
            if initial_wifi_state != cur_wifi_state:
                raise signals.TestFailure(
                    "Wifi state was %d before softAP and %d now!" %
                    (initial_wifi_state, cur_wifi_state))
示例#25
0
    def test_rtt_in_and_after_softap_mode(self):
        """Verify behavior when a SoftAP is enabled and then disabled on the
        device:

        - SAP Enabled: depending on device characteristics RTT may succeed or
                       fail.
        - SAP Disabled: RTT must now succeed.
        """
        supp_required_params = ("dbs_supported_models", )
        self.unpack_userparams(supp_required_params)

        dut = self.android_devices[0]

        rtt_supporting_aps = rutils.select_best_scan_results(
            rutils.scan_with_rtt_support_constraint(dut, True, repeat=10),
            select_count=1)
        dut.log.debug("RTT Supporting APs=%s", rtt_supporting_aps)

        # phase 1 (pre-SAP)
        events = rutils.run_ranging(dut, rtt_supporting_aps, self.NUM_ITER,
                                    self.TIME_BETWEEN_ITERATIONS)
        stats = rutils.analyze_results(events, self.rtt_reference_distance_mm,
                                       self.rtt_reference_distance_margin_mm,
                                       self.rtt_min_expected_rssi_dbm,
                                       self.lci_reference, self.lcr_reference)
        dut.log.debug("Stats Phase 1 (pre-SAP)=%s", stats)

        for bssid, stat in stats.items():
            asserts.assert_true(
                stat['num_no_results'] == 0,
                "Phase 1 (pre-SAP) missing (timed-out) results",
                extras=stats)

        # phase 2 (SAP)
        wutils.start_wifi_tethering(dut,
                                    self.SOFT_AP_SSID,
                                    self.SOFT_AP_PASSWORD,
                                    band=WIFI_CONFIG_APBAND_5G,
                                    hidden=False)
        time.sleep(self.WAIT_FOR_CONFIG_CHANGES_SEC)

        if dut.model not in self.dbs_supported_models:
            rutils.wait_for_event(dut,
                                  rconsts.BROADCAST_WIFI_RTT_NOT_AVAILABLE)
            asserts.assert_false(dut.droid.wifiIsRttAvailable(),
                                 "RTT is available")

        events = rutils.run_ranging(dut, rtt_supporting_aps, self.NUM_ITER,
                                    self.TIME_BETWEEN_ITERATIONS)
        stats = rutils.analyze_results(events, self.rtt_reference_distance_mm,
                                       self.rtt_reference_distance_margin_mm,
                                       self.rtt_min_expected_rssi_dbm,
                                       self.lci_reference, self.lcr_reference)
        dut.log.debug("Stats Phase 2 (SAP)=%s", stats)

        for bssid, stat in stats.items():
            if dut.model in self.dbs_supported_models:
                asserts.assert_true(
                    stat['num_no_results'] == 0,
                    "Phase 2 (SAP) missing (timed-out) results",
                    extras=stats)
            else:
                asserts.assert_true(
                    stat['num_success_results'] == 0,
                    "Phase 2 (SAP) valid results - but unexpected in SAP!?",
                    extras=stats)

        # phase 3 (post-SAP)

        # enabling Wi-Fi first: on some devices this will also disable SAP
        # (that's the scenario we're primarily testing). Additionally,
        # explicitly disable SAP (which may be a NOP on some devices).
        wutils.wifi_toggle_state(dut, True)
        time.sleep(self.WAIT_FOR_CONFIG_CHANGES_SEC)
        wutils.stop_wifi_tethering(dut)

        if dut.model not in self.dbs_supported_models:
            rutils.wait_for_event(dut, rconsts.BROADCAST_WIFI_RTT_AVAILABLE)
            asserts.assert_true(dut.droid.wifiIsRttAvailable(),
                                "RTT is not available")

        events = rutils.run_ranging(dut, rtt_supporting_aps, self.NUM_ITER,
                                    self.TIME_BETWEEN_ITERATIONS)
        stats = rutils.analyze_results(events, self.rtt_reference_distance_mm,
                                       self.rtt_reference_distance_margin_mm,
                                       self.rtt_min_expected_rssi_dbm,
                                       self.lci_reference, self.lcr_reference)
        dut.log.debug("Stats Phase 3 (post-SAP)=%s", stats)

        for bssid, stat in stats.items():
            asserts.assert_true(
                stat['num_no_results'] == 0,
                "Phase 3 (post-SAP) missing (timed-out) results",
                extras=stats)
    def run_aware_then_connect_to_new_ap(self):
        """Validate interaction of Wi-Fi Aware and infra (STA) association with randomized MAC
    address. Such an association may trigger interface down and up - possibly disrupting a Wi-Fi
    Aware session.

    Test behavior:
    - Start Aware
    - Associate STA
    - Check if an Aware state change Broadcast received
    - If necessary (Broadcast received) restart Aware
    - Start publish
    - Start Subscribe on peer
    - Verify discovery
    """
        dut = self.android_devices[0]
        dut_ap = self.android_devices[1]
        wutils.reset_wifi(dut)
        wutils.reset_wifi(dut_ap)
        p_config = autils.create_discovery_config(
            self.SERVICE_NAME, aconsts.PUBLISH_TYPE_UNSOLICITED)
        s_config = autils.create_discovery_config(
            self.SERVICE_NAME, aconsts.SUBSCRIBE_TYPE_PASSIVE)

        # create random SSID and start softAp on dut_ap
        ap_ssid = self.TETHER_SSID + utils.rand_ascii_str(8)
        ap_password = utils.rand_ascii_str(8)
        config = {
            wutils.WifiEnums.SSID_KEY: ap_ssid,
            wutils.WifiEnums.PWD_KEY: ap_password
        }
        wutils.start_wifi_tethering(dut_ap, ap_ssid, ap_password)
        asserts.assert_true(dut_ap.droid.wifiIsApEnabled(),
                            "SoftAp is not reported as running")

        # dut start Aware attach and connect to softAp on dut_ap
        p_id = dut.droid.wifiAwareAttach()
        autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED)

        wutils.wifi_connect(dut, config, check_connectivity=False)
        autils.wait_for_event(dut, wconsts.WIFI_STATE_CHANGED)

        # Check if the WifiAwareState changes then restart the Aware
        try:
            dut.ed.pop_event(aconsts.BROADCAST_WIFI_AWARE_AVAILABLE,
                             EVENT_TIMEOUT)
            dut.log.info(aconsts.BROADCAST_WIFI_AWARE_AVAILABLE)
            p_id = dut.droid.wifiAwareAttach()
            autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED)
        except queue.Empty:
            dut.log.info('WifiAware state was not changed')

        # dut start Publish
        p_disc_id = dut.droid.wifiAwarePublish(p_id, p_config)
        autils.wait_for_event(dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED)

        # dut_ap stop softAp and start Subscribe
        wutils.stop_wifi_tethering(dut_ap)
        autils.wait_for_event(dut_ap, aconsts.BROADCAST_WIFI_AWARE_AVAILABLE)
        s_id = dut_ap.droid.wifiAwareAttach()
        autils.wait_for_event(dut_ap, aconsts.EVENT_CB_ON_ATTACHED)
        s_disc_id = dut_ap.droid.wifiAwareSubscribe(s_id, s_config)
        autils.wait_for_event(dut_ap, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED)

        # Check discovery session
        autils.wait_for_event(dut_ap, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED)
    def _test_data_usage_limit_downlink(self,
                                        dut_a,
                                        dut_b,
                                        file_link,
                                        data_usage,
                                        tethering=False):
        """Verify data usage limit reached.

        Steps:
            1. Set the data usage limit to current data usage + 10MB
            2. If tested for tethered device, start wifi hotspot and
               connect DUT to it.
            3. If tested for tethered device, download 20MB data from
               tethered device else download on the same DUT
            4. Verify file download stops and data limit reached

        Args:
            dut_a: DUT on which data usage limit needs to be verified
            dut_b: DUT on which data needs to be downloaded
            file_link: specifies if the link is IPv4 or IPv6
            data_usage: specifies if MOBILE or WIFI data usage
            tethering: if wifi hotspot should be enabled on dut_a
        """
        sub_id = str(dut_a.droid.telephonyGetSubscriberId())

        # enable hotspot and connect dut_b to it.
        if tethering:
            ssid = "hs_%s" % utils.rand_ascii_str(AP_SSID_LENGTH_2G)
            pwd = utils.rand_ascii_str(AP_PASSPHRASE_LENGTH_2G)
            network = {wutils.WifiEnums.SSID_KEY: ssid,
                       wutils.WifiEnums.PWD_KEY: pwd}
            dut_b.droid.telephonyToggleDataConnection(False)
            wutils.start_wifi_tethering(dut_a,
                                        network[wutils.WifiEnums.SSID_KEY],
                                        network[wutils.WifiEnums.PWD_KEY])
            self.hs_enabled.append(dut_a)
            wutils.start_wifi_connection_scan_and_ensure_network_found(
                dut_b, network[wutils.WifiEnums.SSID_KEY])
            wutils.wifi_connect(dut_b, network)

        # get pre mobile data usage
        total_pre = self._get_total_data_usage_for_device(dut_a, data_usage)

        # set data usage limit to current usage limit + 10MB
        self.log.info("Set data usage limit to %sMB" % (total_pre + INC_DATA))
        dut_a.droid.connectivitySetDataUsageLimit(
            sub_id, int((total_pre + INC_DATA) * BYTE_TO_MB_ANDROID))

        # download file on dut_b and look for BlockedStatusChanged callback
        q = queue.Queue()
        t = threading.Thread(target=self._listen_for_network_callback,
                             args=(dut_a, "BlockedStatusChanged", q))
        t.daemon = True
        t.start()
        status = http_file_download_by_chrome(
            dut_b, file_link, self.file_size, True, TIMEOUT)
        t.join()
        cb_res = q.get()

        # verify file download fails and expected callback is recevied
        asserts.assert_true(cb_res,
                            "Failed to verify blocked status network callback")
        asserts.assert_true(not status,
                            "File download successful. Expected to fail")
    def _test_data_usage_downlink(self,
                                  dut_a,
                                  dut_b,
                                  file_link,
                                  data_usage,
                                  tethering=False,
                                  connect_wifi=False,
                                  app_inc=True):
        """Verify data usage.

        Steps:
            1. Get the current data usage of ConnUIDTest and Android OS apps
            2. DUT is on LTE data (on wifi if connect_wifi is True)
            3. Download file of size xMB through ConnUIDTest app
            4. Verify that data usage of Android OS app did not change
            5. Verify that data usage of ConnUIDTest app increased by ~xMB
            6. Verify that data usage of device also increased by ~xMB

        Args:
            dut_a: DUT on which data usage need to be verified
            dut_b: DUT on which data is downloaded
            file_link: Link used to download data
            data_usage: specifies if MOBILE or WIFI data is calculated
            tethering: if True, enable hotspot on dut_a and connect dut_b to it
            connect_wifi: if True, connect dut_a to a wifi network
            app_inc: if True, verify app data usage on dut_a is increased
        """
        if connect_wifi:
            dut_a.droid.telephonyToggleDataConnection(False)
            wutils.start_wifi_connection_scan_and_ensure_network_found(
                dut_a, self.wifi_network["SSID"])
            wutils.wifi_connect(dut_a, self.wifi_network)
            # sleep for some time after connecting to wifi. some apps use wifi
            # data when connected initially. waiting after connecting to wifi
            # ensures correct wifi data usage calculation
            time.sleep(WIFI_SLEEP)

        if tethering:
            ssid = "hs_%s" % utils.rand_ascii_str(AP_SSID_LENGTH_2G)
            pwd = utils.rand_ascii_str(AP_PASSPHRASE_LENGTH_2G)
            network = {wutils.WifiEnums.SSID_KEY: ssid,
                       wutils.WifiEnums.PWD_KEY: pwd}
            dut_b.droid.telephonyToggleDataConnection(False)
            wutils.start_wifi_tethering(dut_a,
                                        network[wutils.WifiEnums.SSID_KEY],
                                        network[wutils.WifiEnums.PWD_KEY])
            self.hs_enabled.append(dut_a)
            wutils.start_wifi_connection_scan_and_ensure_network_found(
                dut_b, network[wutils.WifiEnums.SSID_KEY])
            wutils.wifi_connect(dut_b, network)
            # sleep for some time after connecting to wifi. though wifi hotspot
            # is metered, some apps would still use wifi data when connected
            # initially. this ensures correct wifi data usage calculation
            time.sleep(WIFI_SLEEP)

        # get pre data usage
        (aos_pre, app_pre, total_pre) = self._get_data_usage(dut_a, data_usage)

        # download file through app
        status = self._download_data_through_app(dut_b, file_link)
        asserts.assert_true(status, "Failed to download file: %s" % file_link)

        # get new data usage
        aos_exp = DATA_ERR
        app_exp = self.file_size + DATA_USG_ERR
        file_size = self.file_size
        if not app_inc:
            app_exp = DATA_ERR
            file_size = 0
        total_exp = self.file_size + DATA_USG_ERR

        # somtimes data usage is not increased immediately.
        # re-tries until the data usage is closed to expected value.
        curr_time = time.time()
        while time.time() < curr_time + TIMEOUT:
            (aos_pst, app_pst, total_pst) = self._get_data_usage(dut_a,
                                                                 data_usage)
            if total_pst - total_pre >= self.file_size and \
                app_pst - app_pre >= file_size:
                  # wait for some time to verify that data doesn't increase
                  time.sleep(RETRY_SLEEP*2)
                  break
            time.sleep(RETRY_SLEEP)  # wait before retry
        (aos_pst, app_pst, total_pst) = self._get_data_usage(dut_a, data_usage)

        # verify data usage
        aos_diff = aos_pst - aos_pre
        app_diff = app_pst - app_pre
        total_diff = total_pst - total_pre
        self.log.info("Usage of Android OS increased: %sMB, expected: %sMB" % \
                      (aos_diff, aos_exp))
        self.log.info("Usage of ConnUID app increased: %sMB, expected: %sMB" % \
                      (app_diff, app_exp))
        self.log.info("Usage on the device increased: %sMB, expected: %sMB" % \
                      (total_diff, total_exp))

        asserts.assert_true(
            (aos_diff < aos_exp) and (file_size <= app_diff < app_exp) and \
                (self.file_size <= total_diff < total_exp),
            "Incorrect data usage count")
    def test_rtt_to_soft_ap(self):
        """Set up a Soft AP on one device and try performing an RTT ranging to it
    from another device. The attempt must fail - RTT on Soft AP must be
    disabled."""
        sap = self.android_devices[0]
        sap.pretty_name = "SoftAP"
        client = self.android_devices[1]
        client.pretty_name = "Client"

        # start Soft AP
        wutils.start_wifi_tethering(sap,
                                    self.SOFT_AP_SSID,
                                    self.SOFT_AP_PASSWORD,
                                    band=WIFI_CONFIG_APBAND_5G,
                                    hidden=False)

        try:
            # start scanning on the client
            wutils.start_wifi_connection_scan_and_ensure_network_found(
                client, self.SOFT_AP_SSID)
            scans = client.droid.wifiGetScanResults()
            scanned_softap = None
            for scanned_ap in scans:
                if scanned_ap[wutils.WifiEnums.SSID_KEY] == self.SOFT_AP_SSID:
                    scanned_softap = scanned_ap
                    break

            asserts.assert_false(scanned_softap == None,
                                 "Soft AP not found in scan!",
                                 extras=scans)

            # validate that Soft AP does not advertise 802.11mc support
            asserts.assert_false(
                rconsts.SCAN_RESULT_KEY_RTT_RESPONDER in scanned_softap
                and scanned_softap[rconsts.SCAN_RESULT_KEY_RTT_RESPONDER],
                "Soft AP advertises itself as supporting 802.11mc!",
                extras=scanned_softap)

            # falsify the SoftAP's support for IEEE 802.11 so we try a 2-sided RTT
            scanned_softap[
                rconsts.SCAN_RESULT_KEY_RTT_RESPONDER] = True  # falsify

            # actually try ranging to the Soft AP
            events = rutils.run_ranging(client, [scanned_softap],
                                        self.NUM_ITER, 0)
            stats = rutils.analyze_results(
                events, self.rtt_reference_distance_mm,
                self.rtt_reference_distance_margin_mm,
                self.rtt_min_expected_rssi_dbm, self.lci_reference,
                self.lcr_reference)

            asserts.assert_equal(
                stats[scanned_ap[wutils.WifiEnums.BSSID_KEY]]['num_failures'],
                self.NUM_ITER,
                "Some RTT operations to Soft AP succeed!?",
                extras=stats)

            asserts.explicit_pass("SoftAP + RTT validation done",
                                  extras=events)
        finally:
            wutils.stop_wifi_tethering(sap)