#!/usr/bin/env python2

# 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 base64
import json
import logging
import logging.handlers

import common
from autotest_lib.client.common_lib.cros.bluetooth import bluetooth_sdp_socket
from autotest_lib.client.common_lib.cros.bluetooth import bluetooth_socket
from autotest_lib.client.cros import constants
from autotest_lib.client.cros import xmlrpc_server


class BluetoothTesterXmlRpcDelegate(xmlrpc_server.XmlRpcDelegate):
    """Exposes Tester methods called remotely during Bluetooth autotests.

    All instance methods of this object without a preceding '_' are exposed via
    an XML-RPC server. This is not a stateless handler object, which means that
    if you store state inside the delegate, that state will remain around for
    future calls.
    """

    BR_EDR_LE_PROFILE = (
            bluetooth_socket.MGMT_SETTING_POWERED |
            bluetooth_socket.MGMT_SETTING_CONNECTABLE |
            bluetooth_socket.MGMT_SETTING_PAIRABLE |
            bluetooth_socket.MGMT_SETTING_SSP |
            bluetooth_socket.MGMT_SETTING_BREDR |
            bluetooth_socket.MGMT_SETTING_LE)

    LE_PROFILE = (
            bluetooth_socket.MGMT_SETTING_POWERED |
            bluetooth_socket.MGMT_SETTING_CONNECTABLE |
            bluetooth_socket.MGMT_SETTING_PAIRABLE |
            bluetooth_socket.MGMT_SETTING_LE)

    PROFILE_SETTINGS = {
        'computer': BR_EDR_LE_PROFILE,
        'peripheral': LE_PROFILE
    }

    # Class of device/service. This can be generated using
    # http://bluetooth-pentest.narod.ru/software/bluetooth_class_of_device-service_generator.html

    PROFILE_CLASS = {
        'computer': 0x000104, # Desktop computer.
        'peripheral': 0x000504 # Keyboard.
    }

    PROFILE_NAMES = {
        'computer': ('ChromeOS Bluetooth Tester', 'Tester'),
        'peripheral': ('ChromeOS Bluetooth Tester', 'Tester')
    }


    def __init__(self):
        super(BluetoothTesterXmlRpcDelegate, self).__init__()

        # Open the Bluetooth Control socket to the kernel which provides us
        # the needed raw management access to the Bluetooth Host Subsystem.
        self._control = bluetooth_socket.BluetoothControlSocket()
        # Open the Bluetooth SDP socket to the kernel which provides us the
        # needed interface to use SDP commands.
        self._sdp = bluetooth_sdp_socket.BluetoothSDPSocket()
        # This is almost a constant, but it might not be forever.
        self.index = 0


    def setup(self, profile):
        """Set up the tester with the given profile.

        @param profile: Profile to use for this test, valid values are:
                computer - a standard computer profile

        @return True on success, False otherwise.

        """
        profile_settings = self.PROFILE_SETTINGS[profile]
        profile_class = self.PROFILE_CLASS[profile]
        (profile_name, profile_short_name) = self.PROFILE_NAMES[profile]

        # b:144864466 In this class's functions, we create local sockets, as
        # stale socket can result in memory allocation error
        _control = bluetooth_socket.BluetoothControlSocket()

        # Make sure the controller actually exists.
        if self.index not in _control.read_index_list():
            logging.warning('Bluetooth Controller missing on tester')
            return False

        # Make sure all of the settings are supported by the controller.
        ( address, bluetooth_version, manufacturer_id,
          supported_settings, current_settings, class_of_device,
          name, short_name ) = _control.read_info(self.index)
        if profile_settings & supported_settings != profile_settings:
            logging.warning('Controller does not support requested settings')
            logging.debug('Supported: %b; Requested: %b', supported_settings,
                          profile_settings)
            return False

        # The high 8 bits of class_of_device is part of Class of Service field
        # which are not actually updated in kernel with
        # _control.set_device_class() below due to a bug in kernel
        # mgmt.c: set_dev_class(). Hence, we should keep these bits in
        # profile_class to make the test setup correctly.
        # Refer to this link about Class of Device/Service bits.
        #   https://www.bluetooth.com/specifications/assigned-numbers/baseband
        # Since the class of device is used as an indication only and is not
        # practically useful in autotest, the service class bits are just
        # copied from previous _control.read_info() request.
        # Refer to Bluetooth Spec. 4.2, "Vol 3, Part C, 3.2.4.4 Usage" about
        # why it is not actually important.
        # Refer to "Vol 2. Part E, 7.3.26 Write Class of Device Command" about
        # the correct parameters to pass to set_device_class() which require
        # 3 bytes instead of 2 bytes.
        # Remove the following statement which modifies profile_class only
        # when kernel is fixed and 3 bytes are passed in set_dev_class().
        # However, this is of very low priority.
        profile_class = ((class_of_device & 0xFF0000) |
                         (profile_class & 0x00FFFF))

        # Class of Device/Service is set to 0 when only LE is enabled and it is
        # set when BR_EDR is enabled . So the first byte of class_of_device will
        # differ when adapter is changed from LE only to BR_EDR + LE.
        # Ignore difference in first byte of class_of_device if that is the case
        # Check if we are changing from LE to BREDR
        le_to_bredr = bool((current_settings & bluetooth_socket.MGMT_SETTING_LE)
                           and (profile_settings
                                & bluetooth_socket.MGMT_SETTING_BREDR))

        # Before beginning, force the adapter power off, even if it's already
        # off; this is enough to persuade an AP-mode Intel chip to accept
        # settings.
        if not _control.set_powered(self.index, False):
            logging.warning('Failed to power off adapter to accept settings')
            return False

        # Set the controller up as either BR/EDR only, LE only or Dual Mode.
        # This is a bit tricky because it rejects commands outright unless
        # it's in dual mode, so we actually have to figure out what changes
        # we have to make, and we have to turn things on before we turn them
        # off.
        turn_on = (current_settings ^ profile_settings) & profile_settings
        if turn_on & bluetooth_socket.MGMT_SETTING_BREDR:
            if _control.set_bredr(self.index, True) is None:
                logging.warning('Failed to enable BR/EDR')
                return False
        if turn_on & bluetooth_socket.MGMT_SETTING_LE:
            if _control.set_le(self.index, True) is None:
                logging.warning('Failed to enable LE')
                return False

        turn_off = (current_settings ^ profile_settings) & current_settings
        if turn_off & bluetooth_socket.MGMT_SETTING_BREDR:
            if _control.set_bredr(self.index, False) is None:
                logging.warning('Failed to disable BR/EDR')
                return False
        if turn_off & bluetooth_socket.MGMT_SETTING_LE:
            if _control.set_le(self.index, False) is None:
                logging.warning('Failed to disable LE')
                return False
        if turn_off & bluetooth_socket.MGMT_SETTING_SECURE_CONNECTIONS:
            if _control.set_secure_connections(self.index, False) is None:
                logging.warning('Failed to disable secure connections')
                return False

        # Adjust settings that are BR/EDR specific that we need to set before
        # powering on the adapter, and would be rejected otherwise.
        if profile_settings & bluetooth_socket.MGMT_SETTING_BREDR:
            if (_control.set_link_security(
                    self.index,
                    (profile_settings &
                            bluetooth_socket.MGMT_SETTING_LINK_SECURITY))
                        is None):
                logging.warning('Failed to set link security setting')
                return False
            if (_control.set_ssp(
                    self.index,
                    profile_settings & bluetooth_socket.MGMT_SETTING_SSP)
                        is None):
                logging.warning('Failed to set SSP setting')
                return False
            if (_control.set_hs(
                    self.index,
                    profile_settings & bluetooth_socket.MGMT_SETTING_HS)
                        is None):
                logging.warning('Failed to set High Speed setting')
                return False

            # Split our the major and minor class; it's listed as a kernel bug
            # that we supply these to the kernel without shifting the bits over
            # to take out the CoD format field, so this might have to change
            # one day.
            major_class = (profile_class & 0x00ff00) >> 8
            minor_class = profile_class & 0x0000ff
            if (_control.set_device_class(
                    self.index, major_class, minor_class)
                        is None):
                logging.warning('Failed to set device class')
                return False

        # Setup generic settings that apply to either BR/EDR, LE or dual-mode
        # that still require the power to be off.
        if (_control.set_connectable(
                self.index,
                profile_settings & bluetooth_socket.MGMT_SETTING_CONNECTABLE)
                    is None):
            logging.warning('Failed to set connectable setting')
            return False
        if (_control.set_pairable(
                self.index,
                profile_settings & bluetooth_socket.MGMT_SETTING_PAIRABLE)
                    is None):
            logging.warning('Failed to set pairable setting')
            return False

        if (_control.set_local_name(
                    self.index, profile_name, profile_short_name)
                    is None):
            logging.warning('Failed to set local name')
            return False

        # Check and set discoverable property
        if ((profile_settings ^ current_settings) &
                    bluetooth_socket.MGMT_SETTING_DISCOVERABLE):
            logging.debug('Set discoverable to %x ',
                          profile_settings &
                          bluetooth_socket.MGMT_SETTING_DISCOVERABLE)
            if _control.set_discoverable(
                   self.index,
                   profile_settings &
                   bluetooth_socket.MGMT_SETTING_DISCOVERABLE) is None:
                logging.warning('Failed to set discoverable setting')
                return False

        # Now the settings have been set, power up the adapter.
        if not _control.set_powered(
                self.index,
                profile_settings & bluetooth_socket.MGMT_SETTING_POWERED):
            logging.warning('Failed to set powered setting')
            return False

        # Fast connectable can only be set once the controller is powered,
        # and only when BR/EDR is enabled.
        if profile_settings & bluetooth_socket.MGMT_SETTING_BREDR:
            # Wait for the device class set event, this happens after the
            # power up "command complete" event when we've pre-set the class
            # even though it's a side-effect of doing that.
            _control.wait_for_events(
                    self.index,
                    ( bluetooth_socket.MGMT_EV_CLASS_OF_DEV_CHANGED, ))

            if (_control.set_fast_connectable(
                    self.index,
                    profile_settings &
                    bluetooth_socket.MGMT_SETTING_FAST_CONNECTABLE)
                        is None):
                logging.warning('Failed to set fast connectable setting')
                return False

        # Fetch the settings again and make sure they're all set correctly,
        # including the BR/EDR flag.
        ( address, bluetooth_version, manufacturer_id,
          supported_settings, current_settings, class_of_device,
          name, short_name ) = _control.read_info(self.index)

        # Check generic settings.
        if profile_settings != current_settings:
            logging.warning('Controller settings did not match those set: '
                            '%x != %x', current_settings, profile_settings)
            return False
        if name != profile_name:
            logging.warning('Local name did not match that set: "%s" != "%s"',
                            name, profile_name)
            return False
        elif short_name != profile_short_name:
            logging.warning('Short name did not match that set: "%s" != "%s"',
                            short_name, profile_short_name)
            return False

        # Check BR/EDR specific settings.
        if profile_settings & bluetooth_socket.MGMT_SETTING_BREDR:
            if class_of_device != profile_class:
                if class_of_device & 0x00ffff == profile_class & 0x00ffff:
                    if not le_to_bredr:
                        logging.warning('Class of device matched that set, but '
                                        'Service Class field did not: %x != %x '
                                        'Reboot Tester? ',
                                        class_of_device, profile_class)
                    else:
                        logging.debug('Service Class field differs but it is'
                                      'expected since adapter changed from'
                                      'LE only to BR/EDR')
                        return True
                else:
                    logging.warning('Class of device did not match that set: '
                                    '%x != %x', class_of_device, profile_class)
                return False

        return True


    def set_discoverable(self, discoverable, timeout=0):
        """Set the discoverable state of the controller.

        @param discoverable: Whether controller should be discoverable.
        @param timeout: Timeout in seconds before disabling discovery again,
                ignored when discoverable is False, must not be zero when
                discoverable is True.

        @return True on success, False otherwise.

        """

        _control = bluetooth_socket.BluetoothControlSocket()
        settings = _control.set_discoverable(self.index, discoverable, timeout)
        return settings & bluetooth_socket.MGMT_SETTING_DISCOVERABLE


    def read_info(self):
        """Read the adapter information from the Kernel.

        @return the information as a JSON-encoded tuple of:
          ( address, bluetooth_version, manufacturer_id,
            supported_settings, current_settings, class_of_device,
            name, short_name )

        """

        _control = bluetooth_socket.BluetoothControlSocket()
        return json.dumps(_control.read_info(self.index))


    def set_advertising(self, advertising):
        """Set the whether the controller is advertising via LE.

        @param advertising: Whether controller should advertise via LE.

        @return True on success, False otherwise.

        """

        _control = bluetooth_socket.BluetoothControlSocket()
        settings = _control.set_advertising(self.index, advertising)
        return settings & bluetooth_socket.MGMT_SETTING_ADVERTISING


    def discover_devices(self, br_edr=True, le_public=True, le_random=True):
        """Discover remote devices.

        Activates device discovery and collects the set of devices found,
        returning them as a list.

        @param br_edr: Whether to detect BR/EDR devices.
        @param le_public: Whether to detect LE Public Address devices.
        @param le_random: Whether to detect LE Random Address devices.

        @return List of devices found as JSON-encoded tuples with the format
                (address, address_type, rssi, flags, base64-encoded eirdata),
                or False if discovery could not be started.

        """
        address_type = 0
        if br_edr:
            address_type |= 0x1
        if le_public:
            address_type |= 0x2
        if le_random:
            address_type |= 0x4

        _control = bluetooth_socket.BluetoothControlSocket()
        set_type = _control.start_discovery(self.index, address_type)
        if set_type != address_type:
            logging.warning('Discovery address type did not match that set: '
                            '%x != %x', set_type, address_type)
            return False

        devices = _control.get_discovered_devices(self.index)
        return json.dumps([
                (address, address_type, rssi, flags,
                 base64.encodestring(eirdata))
                for address, address_type, rssi, flags, eirdata in devices
        ])


    def connect(self, address):
        """Connect to device with the given address

        @param address: Bluetooth address.

        """
        self._sdp.connect(address)
        return True


    def service_search_request(self, uuids, max_rec_cnt, preferred_size=32,
                               forced_pdu_size=None, invalid_request=False):
        """Send a Service Search Request

        @param uuids: List of UUIDs (as integers) to look for.
        @param max_rec_cnt: Maximum count of returned service records.
        @param preferred_size: Preffered size of UUIDs in bits (16, 32, or 128).
        @param forced_pdu_size: Use certain PDU size parameter instead of
               calculating actual length of sequence.
        @param invalid_request: Whether to send request with intentionally
               invalid syntax for testing purposes (bool flag).

        @return list of found services' service record handles or Error Code

        """
        return json.dumps(
                self._sdp.service_search_request(
                 uuids, max_rec_cnt, preferred_size, forced_pdu_size,
                 invalid_request)
        )


    def service_attribute_request(self, handle, max_attr_byte_count, attr_ids,
                                  forced_pdu_size=None, invalid_request=None):
        """Send a Service Attribute Request

        @param handle: service record from which attribute values are to be
               retrieved.
        @param max_attr_byte_count: maximum number of bytes of attribute data to
               be returned in the response to this request.
        @param attr_ids: a list, where each element is either an attribute ID
               or a range of attribute IDs.
        @param forced_pdu_size: Use certain PDU size parameter instead of
               calculating actual length of sequence.
        @param invalid_request: Whether to send request with intentionally
               invalid syntax for testing purposes (string with raw request).

        @return list of found attributes IDs and their values or Error Code

        """
        return json.dumps(
                self._sdp.service_attribute_request(
                 handle, max_attr_byte_count, attr_ids, forced_pdu_size,
                 invalid_request)
        )


    def service_search_attribute_request(self, uuids, max_attr_byte_count,
                                         attr_ids, preferred_size=32,
                                         forced_pdu_size=None,
                                         invalid_request=None):
        """Send a Service Search Attribute Request

        @param uuids: list of UUIDs (as integers) to look for.
        @param max_attr_byte_count: maximum number of bytes of attribute data to
               be returned in the response to this request.
        @param attr_ids: a list, where each element is either an attribute ID
               or a range of attribute IDs.
        @param preferred_size: Preffered size of UUIDs in bits (16, 32, or 128).
        @param forced_pdu_size: Use certain PDU size parameter instead of
               calculating actual length of sequence.
        @param invalid_request: Whether to send request with intentionally
               invalid syntax for testing purposes (string to be prepended
               to correct request).

        @return list of found attributes IDs and their values or Error Code

        """
        return json.dumps(
                self._sdp.service_search_attribute_request(
                 uuids, max_attr_byte_count, attr_ids, preferred_size,
                 forced_pdu_size, invalid_request)
        )


if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG)
    handler = logging.handlers.SysLogHandler(address = '/dev/log')
    formatter = logging.Formatter(
            'bluetooth_tester_xmlrpc_server: [%(levelname)s] %(message)s')
    handler.setFormatter(formatter)
    logging.getLogger().addHandler(handler)
    logging.debug('bluetooth_tester_xmlrpc_server main...')
    server = xmlrpc_server.XmlRpcServer(
            'localhost',
            constants.BLUETOOTH_TESTER_XMLRPC_SERVER_PORT)
    server.register_delegate(BluetoothTesterXmlRpcDelegate())
    server.run()
