| # Copyright (c) 2013 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import cgi |
| import logging |
| |
| from autotest_lib.client.bin import utils |
| from autotest_lib.client.common_lib import error |
| from autotest_lib.server.cros.bluetooth import bluetooth_test |
| |
| |
| class bluetooth_Sanity_Discovery(bluetooth_test.BluetoothTest): |
| """ |
| Verify that the client can discover the tester. |
| """ |
| version = 1 |
| |
| # How long should the tester remain discoverable? |
| DISCOVERABLE_TIMEOUT=180 |
| |
| def find_device(self): |
| """Retrieve devices from client and look for tester. |
| |
| @return True if device has been found, False otherwise. |
| |
| """ |
| # Get the set of devices known to the DUT. |
| devices = self.device.get_devices() |
| if devices == False: |
| raise error.TestFail('Could not retrieve devices from DUT') |
| |
| device_found = False |
| for device in devices: |
| if self.tester: |
| if self.address == device['Address']: |
| logging.info('Found tester with RSSI %d', |
| device.get('RSSI')) |
| # Check name as well; if the name and alias fields don't |
| # match, that means it hasn't been requested yet, so |
| # wait until next time. |
| if device.get('Name') != device['Alias']: |
| logging.info('Device name not yet received') |
| continue |
| if device['Alias'] not in self.name_list: |
| raise error.TestFail( |
| 'Tester "%s" is not one of the expected names ' |
| '"%s"' % (device['Alias'], str(self.name_list))) |
| # Found the device |
| device_found = True |
| # Write out the RSSI now we've found it. |
| self.write_perf_keyval({'rssi': int(device.get('RSSI', 0))}) |
| self.output_perf_value('rssi', int(device.get('RSSI', 0)), |
| 'dBm') |
| |
| if self.interactive: |
| item_name = device['Address'].replace(':', '') |
| html = '%s %s' % (cgi.escape(device['Address']), |
| cgi.escape(device['Alias'])) |
| |
| if device['Address'] in self.devices_discovered: |
| self.interactive.replace_list_item(item_name, html) |
| else: |
| self.interactive.append_list_item('devices', item_name, |
| html) |
| self.devices_discovered.append(device['Address']) |
| |
| result = self.interactive.check_for_button() |
| if result == 0: |
| device_found = True |
| elif result != -1: |
| raise error.TestFail('User indicated test failed') |
| |
| return device_found |
| |
| |
| def run_once(self): |
| """Running bluetooth test to discover a remote discoverable device.""" |
| # Reset the adapter to the powered on state. |
| if not self.device.reset_on(): |
| raise error.TestFail('DUT could not be reset to initial state') |
| |
| if self.tester: |
| # Setup the tester as a generic computer. |
| if not self.tester.setup('computer'): |
| raise error.TestFail('Tester could not be initialized') |
| # Make the tester discoverable |
| self.tester.set_discoverable(True, self.DISCOVERABLE_TIMEOUT) |
| # Read the tester information so we know what we're looking for. |
| ( address, bluetooth_version, manufacturer_id, |
| supported_settings, current_settings, class_of_device, |
| name, short_name ) = self.tester.read_info() |
| self.address = address |
| self.name = name |
| self.name_list = [name, short_name] |
| |
| if self.interactive: |
| self.interactive.login() |
| |
| if self.tester: |
| self.interactive.append_output( |
| '<p>The Tester is in the discoverable state. ' |
| '<p>The DUT is in the page scan/discovery state. ' |
| '<p>Please verify that you can discover the tester ' + |
| ('<b>%s</b> with address <b>%s</b> from the device.' % |
| (cgi.escape(self.name), |
| cgi.escape(self.address)))) |
| else: |
| self.interactive.append_output( |
| '<p>The DUT is in the page scan/discovery state. ' |
| '<p>Please verify that you can discover the device.') |
| |
| self.interactive.append_output('<h2>Devices Found</h2>') |
| self.interactive.append_list('devices') |
| self.devices_discovered = [] |
| |
| if self.tester: |
| self.interactive.append_buttons('Tester Found', |
| 'Tester Not Found') |
| else: |
| self.interactive.append_buttons('Device Found', |
| 'Device Not Found') |
| |
| # Discover devices from the DUT. |
| for failed_attempts in range(0, 5): |
| if not self.device.start_discovery(): |
| raise error.TestFail('Could not start discovery on DUT') |
| try: |
| utils.poll_for_condition( |
| condition=self.find_device, |
| desc='Device discovered from DUT', |
| timeout=self.DISCOVERABLE_TIMEOUT) |
| # We only reach this if we find a device. Break out of the |
| # failed_attempts loop to bypass the "reached the end" |
| # condition. |
| break |
| except utils.TimeoutError: |
| # Capture the timeout error and try once more through the |
| # loop. |
| pass |
| finally: |
| if not self.device.stop_discovery(): |
| logging.warning('Failed to stop discovery on DUT') |
| else: |
| # We only reach this if we tried five times to find the device and |
| # failed. |
| raise error.TestFail('DUT could not discover device') |
| # Record how many attempts this took, hopefully we'll one day figure |
| # out a way to reduce this to zero and then the loop above can go |
| # away. |
| self.write_perf_keyval({'failed_attempts': failed_attempts }) |
| self.output_perf_value('failed_attempts', failed_attempts, 'attempts') |
| |
| |
| def cleanup(self): |
| """Set the tester back to undiscoverable.""" |
| if self.tester: |
| self.tester.set_discoverable(False) |
| |
| super(bluetooth_Sanity_Discovery, self).cleanup() |