#!/usr/bin/env python3
#
#   Copyright 2019 - The Android Open Source Project
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.
"""
Prerequisites:
    Windows 10
    Bluetooth PTS installed
    Recommended: Running cmder as Admin: https://cmder.net/

### BEGIN SETUP STEPS###
1. Install latest version of Python for windows:
    https://www.python.org/downloads/windows/

Tested successfully on Python 3.7.3.:
    https://www.python.org/ftp/python/3.7.3/python-3.7.3.exe

2. Launch Powershell and setup PATH:
Setx PATH “%PATH%;C:/Users/<username>/AppData/Local/Programs/Python/Python37-32/Scripts”

3. Launch Cmder as Admin before running any PTS related ACTS tests.


### END SETUP STEPS###


Bluetooth PTS controller.
Mandatory parameters are log_directory and sig_root_directory.

ACTS Config setup:
"BluetoothPtsDevice": {
    "log_directory": "C:\\Users\\fsbtt\\Documents\\Profile Tuning Suite\\Test_Dir",
    "sig_root_directory": "C:\\Program Files (x86)\\Bluetooth SIG"
}

"""
from acts import signals
from datetime import datetime
from threading import Thread

import ctypes
import logging
import os
import subprocess
import time
import xml.etree.ElementTree as ET

from xml.dom import minidom
from xml.etree.ElementTree import Element


class BluetoothPtsDeviceConfigError(signals.ControllerError):
    pass


class BluetoothPtsSnifferError(signals.ControllerError):
    pass


MOBLY_CONTROLLER_CONFIG_NAME = "BluetoothPtsDevice"
ACTS_CONTROLLER_REFERENCE_NAME = "bluetooth_pts_device"

# Prefix to identify final verdict string. This is a PTS specific log String.
VERDICT = 'VERDICT/'

# Verdict strings that are specific to PTS.
VERDICT_STRINGS = {
    'RESULT_PASS': 'PASS',
    'RESULT_FAIL': 'FAIL',
    'RESULT_INCONC': 'INCONC',
    'RESULT_INCOMP':
    'INCOMP',  # Initial final verdict meaning that test has not completed yet.
    'RESULT_NONE':
    'NONE',  # Error verdict usually indicating internal PTS error.
}

# Sniffer ready log message.
SNIFFER_READY = 'SNIFFER/Save and clear complete'

# PTS Log Types as defined by PTS:
LOG_TYPE_GENERAL_TEXT = 0
LOG_TYPE_FIRST = 1
LOG_TYPE_START_TEST_CASE = 1
LOG_TYPE_TEST_CASE_ENDED = 2
LOG_TYPE_START_DEFAULT = 3
LOG_TYPE_DEFAULT_ENDED = 4
LOG_TYPE_FINAL_VERDICT = 5
LOG_TYPE_PRELIMINARY_VERDICT = 6
LOG_TYPE_TIMEOUT = 7
LOG_TYPE_ASSIGNMENT = 8
LOG_TYPE_START_TIMER = 9
LOG_TYPE_STOP_TIMER = 10
LOG_TYPE_CANCEL_TIMER = 11
LOG_TYPE_READ_TIMER = 12
LOG_TYPE_ATTACH = 13
LOG_TYPE_IMPLICIT_SEND = 14
LOG_TYPE_GOTO = 15
LOG_TYPE_TIMED_OUT_TIMER = 16
LOG_TYPE_ERROR = 17
LOG_TYPE_CREATE = 18
LOG_TYPE_DONE = 19
LOG_TYPE_ACTIVATE = 20
LOG_TYPE_MESSAGE = 21
LOG_TYPE_LINE_MATCHED = 22
LOG_TYPE_LINE_NOT_MATCHED = 23
LOG_TYPE_SEND_EVENT = 24
LOG_TYPE_RECEIVE_EVENT = 25
LOG_TYPE_OTHERWISE_EVENT = 26
LOG_TYPE_RECEIVED_ON_PCO = 27
LOG_TYPE_MATCH_FAILED = 28
LOG_TYPE_COORDINATION_MESSAGE = 29

PTS_DEVICE_EMPTY_CONFIG_MSG = "Configuration is empty, abort!"


def create(config):
    if not config:
        raise errors.PTS_DEVICE_EMPTY_CONFIG_MSG
    return get_instance(config)


def destroy(pts):
    try:
        pts[0].clean_up()
    except:
        pts[0].log.error("Failed to clean up properly.")


def get_info(pts_devices):
    """Get information from the BluetoothPtsDevice object.

    Args:
        pts_devices: A list of BluetoothPtsDevice objects although only one
        will ever be specified.

    Returns:
        A dict, representing info for BluetoothPtsDevice object.
    """
    return {
        "address": pts_devices[0].address,
        "sniffer_ready": pts_devices[0].sniffer_ready,
        "ets_manager_library": pts_devices[0].ets_manager_library,
        "log_directory": pts_devices[0].log_directory,
        "pts_installation_directory":
        pts_devices[0].pts_installation_directory,
    }


def get_instance(config):
    """Create BluetoothPtsDevice instance from a dictionary containing
    information related to PTS. Namely the SIG root directory as
    sig_root_directory and the log directory represented by the log_directory.

    Args:
        config: A dict that contains BluetoothPtsDevice device info.

    Returns:
        A list of BluetoothPtsDevice objects.
    """
    result = []
    try:
        log_directory = config.pop("log_directory")
    except KeyError:
        raise BluetoothPtsDeviceConfigError(
            "Missing mandatory log_directory in config.")
    try:
        sig_root_directory = config.pop("sig_root_directory")
    except KeyError:
        example_path = \
            "C:\\\\Program Files (x86)\\\\Bluetooth SIG"
        raise BluetoothPtsDeviceConfigError(
            "Missing mandatory sig_root_directory in config. Example path: {}".
            format(example_path))

    # "C:\\Program Files (x86)\\Bluetooth SIG\\Bluetooth PTS\\bin\\ETSManager.dll"
    ets_manager_library = "{}\\Bluetooth PTS\\bin\\ETSManager.dll".format(
        sig_root_directory)
    # "C:\\Program Files (x86)\\Bluetooth SIG\\Bluetooth PTS\\bin"
    pts_installation_directory = "{}\\Bluetooth PTS\\bin".format(
        sig_root_directory)
    # "C:\\Program Files (x86)\\Bluetooth SIG\\Bluetooth Protocol Viewer"
    pts_sniffer_directory = "{}\\Bluetooth Protocol Viewer".format(
        sig_root_directory)
    result.append(
        BluetoothPtsDevice(ets_manager_library, log_directory,
                           pts_installation_directory, pts_sniffer_directory))
    return result


class BluetoothPtsDevice:
    """Class representing an Bluetooth PTS device and associated functions.

    Each object of this class represents one BluetoothPtsDevice in ACTS.
    """

    _next_action = -1
    _observers = []
    address = ""
    current_implicit_send_description = ""
    devices = []
    extra_answers = []
    log_directory = ""
    log = None
    ics = None
    ixit = None
    profile_under_test = None
    pts_library = None
    pts_profile_mmi_request = ""
    pts_test_result = VERDICT_STRINGS['RESULT_INCOMP']
    sniffer_ready = False
    test_log_directory = ""
    test_log_prefix = ""

    def __init__(self, ets_manager_library, log_directory,
                 pts_installation_directory, pts_sniffer_directory):
        self.log = logging.getLogger()
        if ets_manager_library is not None:
            self.ets_manager_library = ets_manager_library
        self.log_directory = log_directory
        if pts_installation_directory is not None:
            self.pts_installation_directory = pts_installation_directory
        if pts_sniffer_directory is not None:
            self.pts_sniffer_directory = pts_sniffer_directory
        # Define callback functions
        self.USEAUTOIMPLSENDFUNC = ctypes.CFUNCTYPE(ctypes.c_bool)
        self.use_auto_impl_send_func = self.USEAUTOIMPLSENDFUNC(
            self.UseAutoImplicitSend)

        self.DONGLE_MSG_FUNC = ctypes.CFUNCTYPE(ctypes.c_bool, ctypes.c_char_p)
        self.dongle_msg_func = self.DONGLE_MSG_FUNC(self.DongleMsg)

        self.DEVICE_SEARCH_MSG_FUNC = ctypes.CFUNCTYPE(ctypes.c_bool,
                                                       ctypes.c_char_p,
                                                       ctypes.c_char_p,
                                                       ctypes.c_char_p)
        self.dev_search_msg_func = self.DEVICE_SEARCH_MSG_FUNC(
            self.DeviceSearchMsg)

        self.LOGFUNC = ctypes.CFUNCTYPE(ctypes.c_bool, ctypes.c_char_p,
                                        ctypes.c_char_p, ctypes.c_char_p,
                                        ctypes.c_int, ctypes.c_void_p)
        self.log_func = self.LOGFUNC(self.Log)

        self.ONIMPLSENDFUNC = ctypes.CFUNCTYPE(ctypes.c_char_p,
                                               ctypes.c_char_p, ctypes.c_int)
        self.onimplsend_func = self.ONIMPLSENDFUNC(self.ImplicitSend)

        # Helps with PTS reliability.
        os.chdir(self.pts_installation_directory)
        # Load EtsManager
        self.pts_library = ctypes.cdll.LoadLibrary(self.ets_manager_library)
        self.log.info("ETS Manager library {0:s} has been loaded".format(
            self.ets_manager_library))
        # If post-logging is turned on all callbacks to LPLOG-type function
        # will be executed after test execution is complete. It is recommended
        # that post-logging is turned on to avoid simultaneous invocations of
        # LPLOG and LPAUTOIMPLICITSEND callbacks.
        self.pts_library.SetPostLoggingEx(True)

        self.xml_root = Element("ARCHIVE")
        version = Element("VERSION")
        version.text = "2.0"
        self.xml_root.append(version)
        self.xml_pts_pixit = Element("PicsPixit")
        self.xml_pts_pixit.text = ""
        self.xml_pts_running_log = Element("LOG")
        self.xml_pts_running_log.text = ""
        self.xml_pts_running_summary = Element("SUMMARY")
        self.xml_pts_running_summary.text = ""

    def clean_up(self):
        # Since we have no insight to the actual PTS library,
        # catch all Exceptions and log them.
        try:
            self.log.info("Cleaning up Stack...")
            self.pts_library.ExitStackEx(self.profile_under_test)
        except Exception as err:
            self.log.error(
                "Failed to clean up BluetoothPtsDevice: {}".format(err))
        try:
            self.log.info("Unregistering Profile...")
            self.pts_library.UnregisterProfileEx.argtypes = [ctypes.c_char_p]
            self.pts_library.UnregisterProfileEx(
                self.profile_under_test.encode())
            self.pts_library.UnRegisterGetDevInfoEx()
        except Exception as err:
            self.log.error(
                "Failed to clean up BluetoothPtsDevice: {}".format(err))
        try:
            self.log.info("Cleaning up Sniffer")
            self.pts_library.SnifferTerminateEx()
        except Exception as err:
            self.log.error(
                "Failed to clean up BluetoothPtsDevice: {}".format(err))
        self.log.info("Cleanup Done.")

    def write_xml_pts_pixit_values_for_current_test(self):
        """ Writes the current PICS and IXIT values to the XML result.
        """
        self.xml_pts_pixit.text = "ICS VALUES:\n\n"
        for key, value in self.ics.items():
            self.xml_pts_pixit.text += "{} {}\n".format(
                key.decode(), value.decode())
        self.xml_pts_pixit.text += "\nIXIT VALUES:\n\n"
        for key, (_, value) in self.ixit.items():
            self.xml_pts_pixit.text += "{} {}\n".format(
                key.decode(), value.decode())

    def set_ics_and_ixit(self, ics, ixit):
        self.ics = ics
        self.ixit = ixit

    def set_profile_under_test(self, profile):
        self.profile_under_test = profile

    def setup_pts(self):
        """Prepares PTS to run tests. This needs to be called in test classes
        after ICS, IXIT, and setting Profile under test.
        Specifically BluetoothPtsDevice functions:
            set_profile_under_test
            set_ics_and_ixit
        """

        # Register layer to test with callbacks
        self.pts_library.RegisterProfileWithCallbacks.argtypes = [
            ctypes.c_char_p, self.USEAUTOIMPLSENDFUNC, self.ONIMPLSENDFUNC,
            self.LOGFUNC, self.DEVICE_SEARCH_MSG_FUNC, self.DONGLE_MSG_FUNC
        ]
        res = self.pts_library.RegisterProfileWithCallbacks(
            self.profile_under_test.encode(), self.use_auto_impl_send_func,
            self.onimplsend_func, self.log_func, self.dev_search_msg_func,
            self.dongle_msg_func)

        self.log.info(
            "Profile has been registered with result {0:d}".format(res))

        # GetDeviceInfo module is for discovering devices and PTS Dongle address
        # Initialize GetDeviceInfo and register it with callbacks
        # First parameter is PTS executable directory
        self.pts_library.InitGetDevInfoWithCallbacks.argtypes = [
            ctypes.c_char_p, self.DEVICE_SEARCH_MSG_FUNC, self.DONGLE_MSG_FUNC
        ]
        res = self.pts_library.InitGetDevInfoWithCallbacks(
            self.pts_installation_directory.encode(), self.dev_search_msg_func,
            self.dongle_msg_func)
        self.log.info(
            "GetDevInfo has been initialized with result {0:d}".format(res))
        # Initialize PTS dongle
        res = self.pts_library.VerifyDongleEx()
        self.log.info(
            "PTS dongle has been initialized with result {0:d}".format(res))

        # Find PTS dongle address
        self.pts_library.GetDongleBDAddress.restype = ctypes.c_ulonglong
        self.address = self.pts_library.GetDongleBDAddress()
        self.address_str = "{0:012X}".format(self.address)
        self.log.info("PTS BD Address 0x{0:s}".format(self.address_str))

        # Initialize Bluetooth Protocol Viewer communication module
        self.pts_library.SnifferInitializeEx()

        # If Bluetooth Protocol Viewer is not running, start it
        if not self.is_sniffer_running():
            self.log.info("Starting Protocol Viewer")
            args = [
                "{}\Executables\Core\FTS.exe".format(
                    self.pts_sniffer_directory),
                '/PTS Protocol Viewer=Generic',
                '/OEMTitle=Bluetooth Protocol Viewer', '/OEMKey=Virtual'
            ]
            subprocess.Popen(args)
            sniffer_timeout = 10
            while not self.is_sniffer_running():
                time.sleep(sniffer_timeout)

        # Register to recieve Bluetooth Protocol Viewer notofications
        self.pts_library.SnifferRegisterNotificationEx()
        self.pts_library.SetParameterEx.argtypes = [
            ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p
        ]

        for ics_name in self.ics:
            res = self.pts_library.SetParameterEx(
                ics_name, b'BOOLEAN', self.ics[ics_name],
                self.profile_under_test.encode())
            if res:
                self.log.info("ICS {0:s} set successfully".format(
                    str(ics_name)))
            else:
                self.log.error("Setting ICS {0:s} value failed".format(
                    str(ics_name)))

        for ixit_name in self.ixit:
            res = self.pts_library.SetParameterEx(
                ixit_name, (self.ixit[ixit_name])[0],
                (self.ixit[ixit_name])[1], self.profile_under_test.encode())
            if res:
                self.log.info("IXIT {0:s} set successfully".format(
                    str(ixit_name)))
            else:
                self.log.error("Setting IXIT {0:s} value failed".format(
                    str(ixit_name)))

        # Prepare directory to store Bluetooth Protocol Viewer output
        if not os.path.exists(self.log_directory):
            os.makedirs(self.log_directory)

        address_b = self.address_str.encode("utf-8")
        self.pts_library.InitEtsEx.argtypes = [
            ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p
        ]

        implicit_send_path = "{}\\implicit_send3.dll".format(
            self.pts_installation_directory).encode()
        res = self.pts_library.InitEtsEx(self.profile_under_test.encode(),
                                         self.log_directory.encode(),
                                         implicit_send_path, address_b)
        self.log.info("ETS has been initialized with result {0:s}".format(
            str(res)))

        # Initialize Host Stack DLL
        self.pts_library.InitStackEx.argtypes = [ctypes.c_char_p]
        res = self.pts_library.InitStackEx(self.profile_under_test.encode())
        self.log.info("Stack has been initialized with result {0:s}".format(
            str(res)))

        # Select to receive Log messages after test is done
        self.pts_library.SetPostLoggingEx.argtypes = [
            ctypes.c_bool, ctypes.c_char_p
        ]
        self.pts_library.SetPostLoggingEx(True,
                                          self.profile_under_test.encode())

        # Clear Bluetooth Protocol Viewer. Dongle message callback will update
        # sniffer_ready automatically. No need to fail setup if the timeout
        # is exceeded since the logs will still be available just not starting
        # from a clean slate. Just post a warning.
        self.sniffer_ready = False
        self.pts_library.SnifferClearEx()
        end_time = time.time() + 10
        while not self.sniffer_ready and time.time() < end_time:
            time.sleep(1)
        if not self.sniffer_ready:
            self.log.warning("Sniffer not cleared. Continuing.")

    def is_sniffer_running(self):
        """ Looks for running Bluetooth Protocol Viewer process

        Returns:
            Returns True if finds one, False otherwise.
        """
        prog = [
            line.split()
            for line in subprocess.check_output("tasklist").splitlines()
        ]
        [prog.pop(e) for e in [0, 1, 2]]
        for task in prog:
            task_name = task[0].decode("utf-8")
            if task_name == "Fts.exe":
                self.log.info("Found FTS process successfully.")
                # Sleep recommended by PTS.
                time.sleep(1)
                return True
        return False

    def UseAutoImplicitSend(self):
        """Callback method that defines Which ImplicitSend will be used.

        Returns:
            True always to inform PTS to use the local implementation.
        """
        return True

    def DongleMsg(self, msg_str):
        """ Receives PTS dongle messages.

        Specifically this receives the Bluetooth Protocol Viewer completed
        save/clear operations.

        Returns:
            True if sniffer is ready, False otherwise.
        """
        msg = (ctypes.c_char_p(msg_str).value).decode("utf-8")
        self.log.info(msg)
        # Sleep recommended by PTS.
        time.sleep(1)
        if SNIFFER_READY in msg:
            self.sniffer_ready = True
        return True

    def DeviceSearchMsg(self, addr_str, name_str, cod_str):
        """ Receives device search messages

        Each device may return multiple messages
        Each message will contain device address and may contain device name and
        COD.

        Returns:
            True always and reports to the callback appropriately.
        """
        addr = (ctypes.c_char_p(addr_str).value).replace(b'\xed',
                                                         b' ').decode("utf-8")
        name = (ctypes.c_char_p(name_str).value).replace(b'\xed',
                                                         b' ').decode("utf-8")
        cod = (ctypes.c_char_p(cod_str).value).replace(b'\xed',
                                                       b' ').decode("utf-8")
        self.devices.append(
            "Device address = {0:s} name = {1:s} cod = {2:s}".format(
                addr, name, cod))
        return True

    def Log(self, log_time_str, log_descr_str, log_msg_str, log_type, project):
        """ Receives PTS log messages.

        Returns:
            True always and reports to the callback appropriately.
        """
        log_time = (ctypes.c_char_p(log_time_str).value).decode("utf-8")
        log_descr = (ctypes.c_char_p(log_descr_str).value).decode("utf-8")
        log_msg = (ctypes.c_char_p(log_msg_str).value).decode("utf-8")
        if "Verdict Description" in log_descr:
            self.xml_pts_running_summary.text += "\t- {}".format(log_msg)
        if "Final Verdict" in log_descr:
            self.xml_pts_running_summary.text += "{}{}\n".format(
                log_descr.strip(), log_msg.strip())
        full_log_msg = "{}{}{}".format(log_time, log_descr, log_msg)
        self.xml_pts_running_log.text += "{}\n".format(str(full_log_msg))

        if ctypes.c_int(log_type).value == LOG_TYPE_FINAL_VERDICT:
            indx = log_msg.find(VERDICT)
            if indx == 0:
                if self.pts_test_result == VERDICT_STRINGS['RESULT_INCOMP']:
                    if VERDICT_STRINGS['RESULT_INCONC'] in log_msg:
                        self.pts_test_result = VERDICT_STRINGS['RESULT_INCONC']
                    elif VERDICT_STRINGS['RESULT_FAIL'] in log_msg:
                        self.pts_test_result = VERDICT_STRINGS['RESULT_FAIL']
                    elif VERDICT_STRINGS['RESULT_PASS'] in log_msg:
                        self.pts_test_result = VERDICT_STRINGS['RESULT_PASS']
                    elif VERDICT_STRINGS['RESULT_NONE'] in log_msg:
                        self.pts_test_result = VERDICT_STRINGS['RESULT_NONE']
        return True

    def ImplicitSend(self, description, style):
        """ ImplicitSend callback

        Implicit Send Styles:
            MMI_Style_Ok_Cancel1 =     0x11041, Simple prompt           | OK, Cancel buttons      | Default: OK
            MMI_Style_Ok_Cancel2 =     0x11141, Simple prompt           | Cancel button           | Default: Cancel
            MMI_Style_Ok1 =            0x11040, Simple prompt           | OK button               | Default: OK
            MMI_Style_Yes_No1 =        0x11044, Simple prompt           | Yes, No buttons         | Default: Yes
            MMI_Style_Yes_No_Cancel1 = 0x11043, Simple prompt           | Yes, No buttons         | Default: Yes
            MMI_Style_Abort_Retry1 =   0x11042, Simple prompt           | Abort, Retry buttons    | Default: Abort
            MMI_Style_Edit1 =          0x12040, Request for data input  | OK, Cancel buttons      | Default: OK
            MMI_Style_Edit2 =          0x12140, Select item from a list | OK, Cancel buttons      | Default: OK

        Handling
            MMI_Style_Ok_Cancel1
                OK = return "OK"
                Cancel = return 0

            MMI_Style_Ok_Cancel2
                OK = return "OK"
                Cancel = return 0

            MMI_Style_Ok1
                OK = return "OK", this version should not return 0

            MMI_Style_Yes_No1
                Yes = return "OK"
                No = return 0

            MMI_Style_Yes_No_Cancel1
                Yes = return "OK"
                No = return 0
                Cancel = has been deprecated

            MMI_Style_Abort_Retry1
                Abort = return 0
                Retry = return "OK"

            MMI_Style_Edit1
                OK = return expected string
                Cancel = return 0

            MMI_Style_Edit2
                OK = return expected string
                Cancel = return 0

        Receives ImplicitSend messages
        Description format is as following:
        {MMI_ID,Test Name,Layer Name}MMI Action\n\nDescription: MMI Description
        """
        descr_str = (ctypes.c_char_p(description).value).decode("utf-8")
        # Sleep recommended by PTS.
        time.sleep(1)
        indx = descr_str.find('}')
        implicit_send_info = descr_str[1:(indx)]
        self.current_implicit_send_description = descr_str[(indx + 1):]
        items = implicit_send_info.split(',')
        implicit_send_info_id = items[0]
        implicit_send_info_test_case = items[1]
        self.pts_profile_mmi_request = items[2]
        self.log.info(
            "OnImplicitSend() has been called with the following parameters:\n"
        )
        self.log.info("\t\tproject_name = {0:s}".format(
            self.pts_profile_mmi_request))
        self.log.info("\t\tid = {0:s}".format(implicit_send_info_id))
        self.log.info(
            "\t\ttest_case = {0:s}".format(implicit_send_info_test_case))
        self.log.info("\t\tdescription = {0:s}".format(
            self.current_implicit_send_description))
        self.log.info("\t\tstyle = {0:#X}".format(ctypes.c_int(style).value))
        self.log.info("")
        try:
            self.next_action = int(implicit_send_info_id)
        except Exception as err:
            self.log.error(
                "Setting verdict to RESULT_FAIL, exception found: {}".format(
                    err))
            self.pts_test_result = VERDICT_STRINGS['RESULT_FAIL']
        res = b'OK'
        if len(self.extra_answers) > 0:
            res = self.extra_answers.pop(0).encode()
        self.log.info("Sending Response: {}".format(res))
        return res

    def log_results(self, test_name):
        """Log results.

        Saves the sniffer results in cfa format and clears the sniffer.

        Args:
            test_name: string, name of the test run.
        """
        self.pts_library.SnifferCanSaveEx.restype = ctypes.c_bool
        canSave = ctypes.c_bool(self.pts_library.SnifferCanSaveEx()).value
        self.pts_library.SnifferCanSaveAndClearEx.restype = ctypes.c_bool
        canSaveClear = ctypes.c_bool(
            self.pts_library.SnifferCanSaveAndClearEx()).value
        file_name = "\\{}.cfa".format(self.test_log_prefix).encode()
        path = self.test_log_directory.encode() + file_name

        if canSave == True:
            self.pts_library.SnifferSaveEx.argtypes = [ctypes.c_char_p]
            self.pts_library.SnifferSaveEx(path)
        else:
            self.pts_library.SnifferSaveAndClearEx.argtypes = [ctypes.c_char_p]
            self.pts_library.SnifferSaveAndClearEx(path)
        end_time = time.time() + 60
        while self.sniffer_ready == False and end_time > time.time():
            self.log.info("Waiting for sniffer to be ready...")
            time.sleep(1)
        if self.sniffer_ready == False:
            raise BluetoothPtsSnifferError(
                "Sniffer not ready after 60 seconds.")

    def execute_test(self, test_name, test_timeout=60):
        """Execute the input test name.

        Preps PTS to run the test and waits up to 2 minutes for all steps
        in the execution to finish. Cleanup of PTS related objects follows
        any test verdict.

        Args:
            test_name: string, name of the test to execute.
        """
        today = datetime.now()
        self.write_xml_pts_pixit_values_for_current_test()
        # TODO: Find out how to grab the PTS version. Temporarily
        # hardcoded to v.7.4.1.2.
        self.xml_pts_pixit.text = (
            "Test Case Started: {} v.7.4.1.2, {} started on {}\n\n{}".format(
                self.profile_under_test, test_name,
                today.strftime("%A, %B %d, %Y, %H:%M:%S"),
                self.xml_pts_pixit.text))

        self.xml_pts_running_summary.text += "Test case : {} started\n".format(
            test_name)
        log_time_formatted = "{:%Y_%m_%d_%H_%M_%S}".format(datetime.now())
        formatted_test_name = test_name.replace('/', '_')
        formatted_test_name = formatted_test_name.replace('-', '_')
        self.test_log_prefix = "{}_{}".format(formatted_test_name,
                                              log_time_formatted)
        self.test_log_directory = "{}\\{}\\{}".format(self.log_directory,
                                                      self.profile_under_test,
                                                      self.test_log_prefix)
        os.makedirs(self.test_log_directory)
        curr_test = test_name.encode()

        self.pts_library.StartTestCaseEx.argtypes = [
            ctypes.c_char_p, ctypes.c_char_p, ctypes.c_bool
        ]
        res = self.pts_library.StartTestCaseEx(
            curr_test, self.profile_under_test.encode(), True)
        self.log.info("Test has been started with result {0:s}".format(
            str(res)))

        # Wait till verdict is received
        self.log.info("Begin Test Execution... waiting for verdict.")
        end_time = time.time() + test_timeout
        while self.pts_test_result == VERDICT_STRINGS[
                'RESULT_INCOMP'] and time.time() < end_time:
            time.sleep(1)
        self.log.info("End Test Execution... Verdict {}".format(
            self.pts_test_result))

        # Clean up after test is done
        self.pts_library.TestCaseFinishedEx.argtypes = [
            ctypes.c_char_p, ctypes.c_char_p
        ]
        res = self.pts_library.TestCaseFinishedEx(
            curr_test, self.profile_under_test.encode())

        self.log_results(test_name)
        self.xml_pts_running_summary.text += "{} finished\n".format(test_name)
        # Add the log results to the XML output
        self.xml_root.append(self.xml_pts_pixit)
        self.xml_root.append(self.xml_pts_running_log)
        self.xml_root.append(self.xml_pts_running_summary)
        rough_string = ET.tostring(self.xml_root,
                                   encoding='utf-8',
                                   method='xml')
        reparsed = minidom.parseString(rough_string)
        with open(
                "{}\\{}.xml".format(self.test_log_directory,
                                    self.test_log_prefix), "w") as writter:
            writter.write(
                reparsed.toprettyxml(indent="  ", encoding="utf-8").decode())

        if self.pts_test_result is VERDICT_STRINGS['RESULT_PASS']:
            return True
        return False

    """Observer functions"""

    def bind_to(self, callback):
        """ Callbacks to add to the observer.
        This is used for DUTS automatic responses (ImplicitSends local
        implementation).
        """
        self._observers.append(callback)

    @property
    def next_action(self):
        return self._next_action

    @next_action.setter
    def next_action(self, action):
        self._next_action = action
        for callback in self._observers:
            callback(self._next_action)

    """End Observer functions"""
