250 lines
12 KiB
Python
250 lines
12 KiB
Python
# 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.
|
|
|
|
from __future__ import absolute_import
|
|
|
|
import logging
|
|
import time
|
|
|
|
import common
|
|
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_adapter_tests
|
|
|
|
DEVICE_ADDRESS = '01:02:03:04:05:06'
|
|
ADDRESS_TYPE = 0
|
|
|
|
class bluetooth_Health_DefaultStateTest(
|
|
bluetooth_adapter_tests.BluetoothAdapterTests):
|
|
"""
|
|
This class implements the default state test
|
|
and all the helper functions it needs.
|
|
"""
|
|
version = 1
|
|
|
|
|
|
|
|
def compare_property(self, bluez_property, mgmt_setting, current_settings):
|
|
""" Compare bluez property value and Kernel property
|
|
|
|
@param bluez_property : Bluez property to be compared
|
|
@param mgmt_setting : Bit mask of management setting
|
|
@param current_settings : Current kernel settings
|
|
@return : True if bluez property and the current settings agree """
|
|
|
|
cur_kernel_value = 1 if mgmt_setting & current_settings else 0
|
|
return bluez_property == cur_kernel_value
|
|
|
|
def default_state_test(self):
|
|
"""Test Default state of Bluetooth adapter after power cycling."""
|
|
|
|
# Reset the adapter to the powered off state.
|
|
self.test_reset_off_adapter()
|
|
|
|
# Kernel default state depends on whether the kernel supports the
|
|
# BR/EDR Allowlist. 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 allowlist.
|
|
( commands, events ) = self.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.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.
|
|
#
|
|
|
|
# Verify that the Bluetooth Daemon sees that it is also powered down,
|
|
# non-discoverable and not discovering devices.
|
|
bluez_properties = self.get_adapter_properties()
|
|
|
|
if bluez_properties['Powered']:
|
|
raise error.TestFail('Bluetooth daemon Powered property does not '
|
|
'match kernel while powered off')
|
|
if not self.compare_property(bluez_properties['Discoverable'],
|
|
bluetooth_socket.MGMT_SETTING_DISCOVERABLE,
|
|
current_settings):
|
|
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.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.test_power_on_adapter()
|
|
current_settings = self.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 the kernel does not supports the BR/EDR allowlist, the adapter
|
|
# should be generically connectable;
|
|
# if it doesn't, then it depends on previous settings.
|
|
if not supports_add_device:
|
|
if not current_settings & bluetooth_socket.MGMT_SETTING_CONNECTABLE:
|
|
raise error.TestFail('Bluetooth adapter is not connectable '
|
|
'though kernel does not support '
|
|
'BR/EDR allowlist')
|
|
|
|
# Verify that the Bluetooth Daemon sees the same state as the kernel
|
|
# and that it's not discovering.
|
|
bluez_properties = self.get_adapter_properties()
|
|
|
|
if not bluez_properties['Powered']:
|
|
raise error.TestFail('Bluetooth daemon Powered property does not '
|
|
'match kernel while powered on')
|
|
if not self.compare_property(bluez_properties['Pairable'],
|
|
bluetooth_socket.MGMT_SETTING_PAIRABLE,
|
|
current_settings):
|
|
raise error.TestFail('Bluetooth daemon Pairable property does not '
|
|
'match kernel while powered on')
|
|
if not self.compare_property(bluez_properties['Discoverable'],
|
|
bluetooth_socket.MGMT_SETTING_DISCOVERABLE,
|
|
current_settings):
|
|
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.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 bool(flags & bluetooth_socket.HCI_ISCAN) != \
|
|
bool(bluez_properties['Discoverable']):
|
|
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 does not supports the BR/EDR allowlist, the adapter
|
|
# should generically connectable, so should it should be in PSCAN
|
|
# mode. This matches the management API "connectable" setting so far.
|
|
if not supports_add_device:
|
|
if not flags & bluetooth_socket.HCI_PSCAN:
|
|
raise error.TestFail('HCI PSCAN flag not set though kernel'
|
|
'does not supports BR/EDR allowlist')
|
|
|
|
# Now we can examine the differences. Try adding and removing a device
|
|
# from the kernel BR/EDR allowlist. 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:
|
|
# If PSCAN is currently on then device is CONNECTABLE
|
|
# or a previous add device which was not removed.
|
|
# Turn on and off DISCOVERABLE to turn off CONNECTABLE and
|
|
# PSCAN
|
|
if flags & bluetooth_socket.HCI_PSCAN:
|
|
if not (current_settings &
|
|
bluetooth_socket.MGMT_SETTING_CONNECTABLE):
|
|
raise error.TestFail('PSCAN on but device not CONNECTABLE')
|
|
logging.debug('Toggle Discoverable to turn off CONNECTABLE')
|
|
self.test_discoverable()
|
|
self.test_nondiscoverable()
|
|
current_settings = self.read_info()[4]
|
|
flags = self.get_dev_info()[3]
|
|
self.log_flags('Discoverability Toggled', flags)
|
|
if flags & bluetooth_socket.HCI_PSCAN:
|
|
raise error.TestFail('PSCAN on after toggling DISCOVERABLE')
|
|
|
|
previous_settings = current_settings
|
|
previous_flags = flags
|
|
|
|
self.add_device(DEVICE_ADDRESS, ADDRESS_TYPE, 1)
|
|
|
|
# Wait for a few seconds before reading the settings
|
|
time.sleep(3)
|
|
current_settings = self.read_info()[4]
|
|
self.log_settings("After add device",
|
|
current_settings)
|
|
|
|
flags = self.get_dev_info()[3]
|
|
self.log_flags('After add device', flags)
|
|
|
|
if current_settings != previous_settings:
|
|
self.log_settings("previous settings", previous_settings)
|
|
self.log_settings("current settings", current_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.remove_device(DEVICE_ADDRESS, ADDRESS_TYPE)
|
|
|
|
# PSCAN is still enabled for a few seconds after remove device
|
|
# on older devices. Wait for few second before reading the settigs
|
|
time.sleep(3)
|
|
current_settings = self.read_info()[4]
|
|
self.log_settings("After remove device", current_settings)
|
|
|
|
flags = self.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 remove device')
|
|
|
|
# Finally power off the adapter again, and verify that the adapter has
|
|
# returned to powered down.
|
|
self.test_power_off_adapter()
|
|
current_settings = self.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')
|
|
|
|
# Verify that the Bluetooth Daemon sees the same state as the kernel.
|
|
bluez_properties = self.get_adapter_properties()
|
|
|
|
if bluez_properties['Powered']:
|
|
raise error.TestFail('Bluetooth daemon Powered property does not '
|
|
'match kernel after power off')
|
|
if not self.compare_property(bluez_properties['Discoverable'],
|
|
bluetooth_socket.MGMT_SETTING_DISCOVERABLE,
|
|
current_settings):
|
|
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.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')
|