Home | History | Annotate | Download | only in bluetooth_Sanity_DefaultState
      1 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 import logging
      6 
      7 from autotest_lib.client.common_lib import error
      8 from autotest_lib.client.common_lib.cros.bluetooth import bluetooth_socket
      9 from autotest_lib.server.cros.bluetooth import bluetooth_test
     10 
     11 
     12 class bluetooth_Sanity_DefaultState(bluetooth_test.BluetoothTest):
     13     """
     14     Verify that the Bluetooth adapter has correct state.
     15     """
     16     version = 1
     17 
     18     def _log_settings(self, msg, settings):
     19         strs = []
     20         if settings & bluetooth_socket.MGMT_SETTING_POWERED:
     21             strs.append("POWERED")
     22         if settings & bluetooth_socket.MGMT_SETTING_CONNECTABLE:
     23             strs.append("CONNECTABLE")
     24         if settings & bluetooth_socket.MGMT_SETTING_FAST_CONNECTABLE:
     25             strs.append("FAST-CONNECTABLE")
     26         if settings & bluetooth_socket.MGMT_SETTING_DISCOVERABLE:
     27             strs.append("DISCOVERABLE")
     28         if settings & bluetooth_socket.MGMT_SETTING_PAIRABLE:
     29             strs.append("PAIRABLE")
     30         if settings & bluetooth_socket.MGMT_SETTING_LINK_SECURITY:
     31             strs.append("LINK-SECURITY")
     32         if settings & bluetooth_socket.MGMT_SETTING_SSP:
     33             strs.append("SSP")
     34         if settings & bluetooth_socket.MGMT_SETTING_BREDR:
     35             strs.append("BR/EDR")
     36         if settings & bluetooth_socket.MGMT_SETTING_HS:
     37             strs.append("HS")
     38         if settings & bluetooth_socket.MGMT_SETTING_LE:
     39             strs.append("LE")
     40         logging.debug(msg + ': %s', " ".join(strs))
     41 
     42     def _log_flags(self, msg, flags):
     43         strs = []
     44         if flags & bluetooth_socket.HCI_UP:
     45             strs.append("UP")
     46         else:
     47             strs.append("DOWN")
     48         if flags & bluetooth_socket.HCI_INIT:
     49             strs.append("INIT")
     50         if flags & bluetooth_socket.HCI_RUNNING:
     51             strs.append("RUNNING")
     52         if flags & bluetooth_socket.HCI_PSCAN:
     53             strs.append("PSCAN")
     54         if flags & bluetooth_socket.HCI_ISCAN:
     55             strs.append("ISCAN")
     56         if flags & bluetooth_socket.HCI_AUTH:
     57             strs.append("AUTH")
     58         if flags & bluetooth_socket.HCI_ENCRYPT:
     59             strs.append("ENCRYPT")
     60         if flags & bluetooth_socket.HCI_INQUIRY:
     61             strs.append("INQUIRY")
     62         if flags & bluetooth_socket.HCI_RAW:
     63             strs.append("RAW")
     64         logging.debug(msg + ' [HCI]: %s', " ".join(strs))
     65 
     66     def run_once(self):
     67         # Reset the adapter to the powered off state.
     68         if not self.device.reset_off():
     69             raise error.TestFail('DUT could not be reset to initial state')
     70 
     71         # Kernel default state depends on whether the kernel supports the
     72         # BR/EDR Whitelist. When this is supported the 'connectable' setting
     73         # remains unset and instead page scan is managed by the kernel based
     74         # on whether or not a BR/EDR device is in the whitelist.
     75         ( commands, events ) = self.device.read_supported_commands()
     76         supports_add_device = bluetooth_socket.MGMT_OP_ADD_DEVICE in commands
     77 
     78         # Read the initial state of the adapter. Verify that it is powered down.
     79         ( address, bluetooth_version, manufacturer_id,
     80                 supported_settings, current_settings, class_of_device,
     81                 name, short_name ) = self.device.read_info()
     82         self._log_settings('Initial state', current_settings)
     83 
     84         if current_settings & bluetooth_socket.MGMT_SETTING_POWERED:
     85             raise error.TestFail('Bluetooth adapter is powered')
     86 
     87         # The other kernel settings (connectable, pairable, etc.) reflect the
     88         # initial state before the bluetooth daemon adjusts them - we're ok
     89         # with them being on or off during that brief period.
     90         #
     91         # Except for discoverable - that one should be off.
     92         if current_settings & bluetooth_socket.MGMT_SETTING_DISCOVERABLE:
     93             raise error.TestFail('Bluetooth adapter would be discoverable '
     94                                  'during power on')
     95 
     96         # Verify that the Bluetooth Daemon sees that it is also powered down,
     97         # non-discoverable and not discovering devices.
     98         bluez_properties = self.device.get_adapter_properties()
     99 
    100         if bluez_properties['Powered']:
    101             raise error.TestFail('Bluetooth daemon Powered property does not '
    102                                  'match kernel while powered off')
    103         if bluez_properties['Discoverable']:
    104             raise error.TestFail('Bluetooth daemon Discoverable property '
    105                                  'does not match kernel while powered off')
    106         if bluez_properties['Discovering']:
    107             raise error.TestFail('Bluetooth daemon believes adapter is '
    108                                  'discovering while powered off')
    109 
    110         # Compare with the raw HCI state of the adapter as well, this should
    111         # be just not "UP", otherwise something deeply screwy is happening.
    112         flags = self.device.get_dev_info()[3]
    113         self._log_flags('Initial state', flags)
    114 
    115         if flags & bluetooth_socket.HCI_UP:
    116             raise error.TestFail('HCI UP flag does not match kernel while '
    117                                  'powered off')
    118 
    119         # Power on the adapter, then read the state again. Verify that it is
    120         # powered up, pairable, but not discoverable.
    121         self.device.set_powered(True)
    122         current_settings = self.device.read_info()[4]
    123         self._log_settings("Powered up", current_settings)
    124 
    125         if not current_settings & bluetooth_socket.MGMT_SETTING_POWERED:
    126             raise error.TestFail('Bluetooth adapter is not powered')
    127         if not current_settings & bluetooth_socket.MGMT_SETTING_PAIRABLE:
    128             raise error.TestFail('Bluetooth adapter is not pairable')
    129 
    130         if current_settings & bluetooth_socket.MGMT_SETTING_DISCOVERABLE:
    131             raise error.TestFail('Bluetooth adapter is discoverable')
    132 
    133         # If the kernel supports the BR/EDR whitelist, the adapter should _not_
    134         # be generically connectable; if it doesn't, it should be.
    135         if supports_add_device:
    136             if current_settings & bluetooth_socket.MGMT_SETTING_CONNECTABLE:
    137                 raise error.TestFail('Bluetooth adapter is connectable')
    138         elif not current_settings & bluetooth_socket.MGMT_SETTING_CONNECTABLE:
    139             raise error.TestFail('Bluetooth adapter is not connectable')
    140 
    141         # Verify that the Bluetooth Daemon sees the same state as the kernel
    142         # and that it's not discovering.
    143         bluez_properties = self.device.get_adapter_properties()
    144 
    145         if not bluez_properties['Powered']:
    146             raise error.TestFail('Bluetooth daemon Powered property does not '
    147                                  'match kernel while powered on')
    148         if not bluez_properties['Pairable']:
    149             raise error.TestFail('Bluetooth daemon Pairable property does not '
    150                                  'match kernel while powered on')
    151 
    152         if bluez_properties['Discoverable']:
    153             raise error.TestFail('Bluetooth daemon Discoverable property '
    154                                  'does not match kernel while powered on')
    155         if bluez_properties['Discovering']:
    156             raise error.TestFail('Bluetooth daemon believes adapter is '
    157                                  'discovering while powered on')
    158 
    159         # Compare with the raw HCI state of the adapter while powered up as
    160         # well.
    161         flags = self.device.get_dev_info()[3]
    162         self._log_flags('Powered up', flags)
    163 
    164         if not flags & bluetooth_socket.HCI_UP:
    165             raise error.TestFail('HCI UP flag does not match kernel while '
    166                                  'powered on')
    167         if not flags & bluetooth_socket.HCI_RUNNING:
    168             raise error.TestFail('HCI RUNNING flag does not match kernel while '
    169                                  'powered on')
    170         if flags & bluetooth_socket.HCI_ISCAN:
    171             raise error.TestFail('HCI ISCAN flag does not match kernel while '
    172                                  'powered on')
    173         if flags & bluetooth_socket.HCI_INQUIRY:
    174             raise error.TestFail('HCI INQUIRY flag does not match kernel while '
    175                                  'powered on')
    176 
    177         # If the kernel supports the BR/EDR whitelist, the adapter isn't
    178         # supposed to be generically connectable, so should _not_ be in PSCAN
    179         # mode yet. If it doesn't, it should be. This matches the management
    180         # API "connectable" setting so far.
    181         if supports_add_device:
    182             if flags & bluetooth_socket.HCI_PSCAN:
    183                 raise error.TestFail('HCI PSCAN flag does not match kernel '
    184                                      'while powered on')
    185         elif not flags & bluetooth_socket.HCI_PSCAN:
    186                 raise error.TestFail('HCI PSCAN flag does not match kernel '
    187                                      'while powered on')
    188 
    189         # Now we can examine the differences. Try adding and removing a device
    190         # from the kernel BR/EDR whitelist. The management API "connectable"
    191         # setting should remain off, but we should be able to see the PSCAN
    192         # flag come and go.
    193         if supports_add_device:
    194             previous_settings = current_settings
    195             previous_flags = flags
    196 
    197             self.device.add_device('01:02:03:04:05:06', 0, 1)
    198 
    199             current_settings = self.device.read_info()[4]
    200             self._log_settings("After add device", current_settings)
    201 
    202             flags = self.device.get_dev_info()[3]
    203             self._log_flags('After add device', flags)
    204 
    205             if current_settings != previous_settings:
    206                 raise error.TestFail(
    207                     'Bluetooth adapter settings changed after add device')
    208             if not flags & bluetooth_socket.HCI_PSCAN:
    209                 raise error.TestFail('HCI PSCAN flag not set after add device')
    210 
    211             # Remove the device again, and make sure the PSCAN flag goes away.
    212             self.device.remove_device('01:02:03:04:05:06', 0)
    213 
    214             current_settings = self.device.read_info()[4]
    215             self._log_settings("After remove device", current_settings)
    216 
    217             flags = self.device.get_dev_info()[3]
    218             self._log_flags('After remove device', flags)
    219 
    220             if current_settings != previous_settings:
    221                 raise error.TestFail(
    222                     'Bluetooth adapter settings changed after remove device')
    223             if flags & bluetooth_socket.HCI_PSCAN:
    224                 raise error.TestFail('HCI PSCAN flag set after add device')
    225 
    226         # Finally power off the adapter again, and verify that the adapter has
    227         # returned to powered down.
    228         self.device.set_powered(False)
    229         current_settings = self.device.read_info()[4]
    230         self._log_settings("After power down", current_settings)
    231 
    232         if current_settings & bluetooth_socket.MGMT_SETTING_POWERED:
    233             raise error.TestFail('Bluetooth adapter is powered after power off')
    234 
    235         if current_settings & bluetooth_socket.MGMT_SETTING_DISCOVERABLE:
    236             raise error.TestFail('Bluetooth adapter would be discoverable '
    237                                  'during next power on')
    238 
    239         # Verify that the Bluetooth Daemon sees the same state as the kernel.
    240         bluez_properties = self.device.get_adapter_properties()
    241 
    242         if bluez_properties['Powered']:
    243             raise error.TestFail('Bluetooth daemon Powered property does not '
    244                                  'match kernel after power off')
    245         if bluez_properties['Discoverable']:
    246             raise error.TestFail('Bluetooth daemon Discoverable property '
    247                                  'does not match kernel after off')
    248         if bluez_properties['Discovering']:
    249             raise error.TestFail('Bluetooth daemon believes adapter is '
    250                                  'discovering after power off')
    251 
    252         # And one last comparison with the raw HCI state of the adapter.
    253         flags = self.device.get_dev_info()[3]
    254         self._log_flags('After power down', flags)
    255 
    256         if flags & bluetooth_socket.HCI_UP:
    257             raise error.TestFail('HCI UP flag does not match kernel after '
    258                                  'power off')
    259