blob: a242f3636a68ca9c78191cf6708c87a9acddca50 [file] [log] [blame]
# 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 logging
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros.bluetooth import bluetooth_socket
from autotest_lib.server.cros.bluetooth import bluetooth_test
class bluetooth_Sanity_DefaultState(bluetooth_test.BluetoothTest):
"""
Verify that the Bluetooth adapter has correct state.
"""
version = 1
def _log_settings(self, msg, settings):
strs = []
if settings & bluetooth_socket.MGMT_SETTING_POWERED:
strs.append("POWERED")
if settings & bluetooth_socket.MGMT_SETTING_CONNECTABLE:
strs.append("CONNECTABLE")
if settings & bluetooth_socket.MGMT_SETTING_FAST_CONNECTABLE:
strs.append("FAST-CONNECTABLE")
if settings & bluetooth_socket.MGMT_SETTING_DISCOVERABLE:
strs.append("DISCOVERABLE")
if settings & bluetooth_socket.MGMT_SETTING_PAIRABLE:
strs.append("PAIRABLE")
if settings & bluetooth_socket.MGMT_SETTING_LINK_SECURITY:
strs.append("LINK-SECURITY")
if settings & bluetooth_socket.MGMT_SETTING_SSP:
strs.append("SSP")
if settings & bluetooth_socket.MGMT_SETTING_BREDR:
strs.append("BR/EDR")
if settings & bluetooth_socket.MGMT_SETTING_HS:
strs.append("HS")
if settings & bluetooth_socket.MGMT_SETTING_LE:
strs.append("LE")
logging.debug(msg + ': %s', " ".join(strs))
def _log_flags(self, msg, flags):
strs = []
if flags & bluetooth_socket.HCI_UP:
strs.append("UP")
else:
strs.append("DOWN")
if flags & bluetooth_socket.HCI_INIT:
strs.append("INIT")
if flags & bluetooth_socket.HCI_RUNNING:
strs.append("RUNNING")
if flags & bluetooth_socket.HCI_PSCAN:
strs.append("PSCAN")
if flags & bluetooth_socket.HCI_ISCAN:
strs.append("ISCAN")
if flags & bluetooth_socket.HCI_AUTH:
strs.append("AUTH")
if flags & bluetooth_socket.HCI_ENCRYPT:
strs.append("ENCRYPT")
if flags & bluetooth_socket.HCI_INQUIRY:
strs.append("INQUIRY")
if flags & bluetooth_socket.HCI_RAW:
strs.append("RAW")
logging.debug(msg + ' [HCI]: %s', " ".join(strs))
def run_once(self):
# Reset the adapter to the powered off state.
if not self.device.reset_off():
raise error.TestFail('DUT could not be reset to initial state')
# Kernel default state depends on whether the kernel supports the
# BR/EDR Whitelist. When this is supported the 'connectable' setting
# remains unset and instead page scan is managed by the kernel based
# on whether or not a BR/EDR device is in the whitelist.
( commands, events ) = self.device.read_supported_commands()
supports_add_device = bluetooth_socket.MGMT_OP_ADD_DEVICE in commands
# Read the initial state of the adapter. Verify that it is powered down.
( address, bluetooth_version, manufacturer_id,
supported_settings, current_settings, class_of_device,
name, short_name ) = self.device.read_info()
self._log_settings('Initial state', current_settings)
if current_settings & bluetooth_socket.MGMT_SETTING_POWERED:
raise error.TestFail('Bluetooth adapter is powered')
# The other kernel settings (connectable, pairable, etc.) reflect the
# initial state before the bluetooth daemon adjusts them - we're ok
# with them being on or off during that brief period.
#
# Except for discoverable - that one should be off.
if current_settings & bluetooth_socket.MGMT_SETTING_DISCOVERABLE:
raise error.TestFail('Bluetooth adapter would be discoverable '
'during power on')
# Verify that the Bluetooth Daemon sees that it is also powered down,
# non-discoverable and not discovering devices.
bluez_properties = self.device.get_adapter_properties()
if bluez_properties['Powered']:
raise error.TestFail('Bluetooth daemon Powered property does not '
'match kernel while powered off')
if bluez_properties['Discoverable']:
raise error.TestFail('Bluetooth daemon Discoverable property '
'does not match kernel while powered off')
if bluez_properties['Discovering']:
raise error.TestFail('Bluetooth daemon believes adapter is '
'discovering while powered off')
# Compare with the raw HCI state of the adapter as well, this should
# be just not "UP", otherwise something deeply screwy is happening.
flags = self.device.get_dev_info()[3]
self._log_flags('Initial state', flags)
if flags & bluetooth_socket.HCI_UP:
raise error.TestFail('HCI UP flag does not match kernel while '
'powered off')
# Power on the adapter, then read the state again. Verify that it is
# powered up, pairable, but not discoverable.
self.device.set_powered(True)
current_settings = self.device.read_info()[4]
self._log_settings("Powered up", current_settings)
if not current_settings & bluetooth_socket.MGMT_SETTING_POWERED:
raise error.TestFail('Bluetooth adapter is not powered')
if not current_settings & bluetooth_socket.MGMT_SETTING_PAIRABLE:
raise error.TestFail('Bluetooth adapter is not pairable')
if current_settings & bluetooth_socket.MGMT_SETTING_DISCOVERABLE:
raise error.TestFail('Bluetooth adapter is discoverable')
# If the kernel supports the BR/EDR whitelist, the adapter should _not_
# be generically connectable; if it doesn't, it should be.
if supports_add_device:
if current_settings & bluetooth_socket.MGMT_SETTING_CONNECTABLE:
raise error.TestFail('Bluetooth adapter is connectable')
elif not current_settings & bluetooth_socket.MGMT_SETTING_CONNECTABLE:
raise error.TestFail('Bluetooth adapter is not connectable')
# Verify that the Bluetooth Daemon sees the same state as the kernel
# and that it's not discovering.
bluez_properties = self.device.get_adapter_properties()
if not bluez_properties['Powered']:
raise error.TestFail('Bluetooth daemon Powered property does not '
'match kernel while powered on')
if not bluez_properties['Pairable']:
raise error.TestFail('Bluetooth daemon Pairable property does not '
'match kernel while powered on')
if bluez_properties['Discoverable']:
raise error.TestFail('Bluetooth daemon Discoverable property '
'does not match kernel while powered on')
if bluez_properties['Discovering']:
raise error.TestFail('Bluetooth daemon believes adapter is '
'discovering while powered on')
# Compare with the raw HCI state of the adapter while powered up as
# well.
flags = self.device.get_dev_info()[3]
self._log_flags('Powered up', flags)
if not flags & bluetooth_socket.HCI_UP:
raise error.TestFail('HCI UP flag does not match kernel while '
'powered on')
if not flags & bluetooth_socket.HCI_RUNNING:
raise error.TestFail('HCI RUNNING flag does not match kernel while '
'powered on')
if flags & bluetooth_socket.HCI_ISCAN:
raise error.TestFail('HCI ISCAN flag does not match kernel while '
'powered on')
if flags & bluetooth_socket.HCI_INQUIRY:
raise error.TestFail('HCI INQUIRY flag does not match kernel while '
'powered on')
# If the kernel supports the BR/EDR whitelist, the adapter isn't
# supposed to be generically connectable, so should _not_ be in PSCAN
# mode yet. If it doesn't, it should be. This matches the management
# API "connectable" setting so far.
if supports_add_device:
if flags & bluetooth_socket.HCI_PSCAN:
raise error.TestFail('HCI PSCAN flag does not match kernel '
'while powered on')
elif not flags & bluetooth_socket.HCI_PSCAN:
raise error.TestFail('HCI PSCAN flag does not match kernel '
'while powered on')
# Now we can examine the differences. Try adding and removing a device
# from the kernel BR/EDR whitelist. The management API "connectable"
# setting should remain off, but we should be able to see the PSCAN
# flag come and go.
if supports_add_device:
previous_settings = current_settings
previous_flags = flags
self.device.add_device('01:02:03:04:05:06', 0, 1)
current_settings = self.device.read_info()[4]
self._log_settings("After add device", current_settings)
flags = self.device.get_dev_info()[3]
self._log_flags('After add device', flags)
if current_settings != previous_settings:
raise error.TestFail(
'Bluetooth adapter settings changed after add device')
if not flags & bluetooth_socket.HCI_PSCAN:
raise error.TestFail('HCI PSCAN flag not set after add device')
# Remove the device again, and make sure the PSCAN flag goes away.
self.device.remove_device('01:02:03:04:05:06', 0)
current_settings = self.device.read_info()[4]
self._log_settings("After remove device", current_settings)
flags = self.device.get_dev_info()[3]
self._log_flags('After remove device', flags)
if current_settings != previous_settings:
raise error.TestFail(
'Bluetooth adapter settings changed after remove device')
if flags & bluetooth_socket.HCI_PSCAN:
raise error.TestFail('HCI PSCAN flag set after add device')
# Finally power off the adapter again, and verify that the adapter has
# returned to powered down.
self.device.set_powered(False)
current_settings = self.device.read_info()[4]
self._log_settings("After power down", current_settings)
if current_settings & bluetooth_socket.MGMT_SETTING_POWERED:
raise error.TestFail('Bluetooth adapter is powered after power off')
if current_settings & bluetooth_socket.MGMT_SETTING_DISCOVERABLE:
raise error.TestFail('Bluetooth adapter would be discoverable '
'during next power on')
# Verify that the Bluetooth Daemon sees the same state as the kernel.
bluez_properties = self.device.get_adapter_properties()
if bluez_properties['Powered']:
raise error.TestFail('Bluetooth daemon Powered property does not '
'match kernel after power off')
if bluez_properties['Discoverable']:
raise error.TestFail('Bluetooth daemon Discoverable property '
'does not match kernel after off')
if bluez_properties['Discovering']:
raise error.TestFail('Bluetooth daemon believes adapter is '
'discovering after power off')
# And one last comparison with the raw HCI state of the adapter.
flags = self.device.get_dev_info()[3]
self._log_flags('After power down', flags)
if flags & bluetooth_socket.HCI_UP:
raise error.TestFail('HCI UP flag does not match kernel after '
'power off')