From 1e6a7371546e9dcb0aac02a0eb4b6fa8db729c2d Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 15 Oct 2024 13:52:15 +0200 Subject: [PATCH 01/32] zephyr: Update PTS workspace to match latest Qualification Studio files This enabled PAST related tests in BAP. --- .../zephyr/zephyr-master/zephyr-master.pqw6 | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/autopts/workspaces/zephyr/zephyr-master/zephyr-master.pqw6 b/autopts/workspaces/zephyr/zephyr-master/zephyr-master.pqw6 index ac013d22d0..14c1546f5f 100755 --- a/autopts/workspaces/zephyr/zephyr-master/zephyr-master.pqw6 +++ b/autopts/workspaces/zephyr/zephyr-master/zephyr-master.pqw6 @@ -4451,25 +4451,25 @@ TSPC_BAP_80_13 Periodic Advertising Synchronization Establishment procedure over an LE connection without listening for periodic advertising (Peripheral) (C.6) - FALSE + TRUE FALSE TSPC_BAP_80_14 Periodic Advertising Synchronization Establishment procedure over an LE connection with listening for periodic advertising (Peripheral) (C.6) - FALSE + TRUE FALSE TSPC_BAP_80_15 Periodic Advertising Synchronization Establishment procedure over an LE connection without listening for periodic advertising (Central) (C.7) - FALSE + TRUE FALSE TSPC_BAP_80_16 Periodic Advertising Synchronization Establishment procedure over an LE connection with listening for periodic advertising (Central) (C.7) - FALSE + TRUE FALSE @@ -4541,7 +4541,7 @@ TSPC_BAP_82_4 Periodic Advertising Sync Transfer - Recipient (O) - FALSE + TRUE FALSE @@ -4667,7 +4667,7 @@ TSPC_BAP_88_5 SyncInfo Transfer (O) - FALSE + TRUE FALSE @@ -4853,13 +4853,13 @@ TSPC_BAP_90_16 Periodic Advertising Synchronization Establishment procedure over an LE connection without listening for periodic advertising (C.8) - FALSE + TRUE FALSE TSPC_BAP_90_17 Periodic Advertising Synchronization Establishment procedure over an LE connection with listening for periodic advertising (C.8) - FALSE + TRUE FALSE @@ -4919,19 +4919,19 @@ TSPC_BAP_92_4 Periodic Advertising Sync Transfer - Sender (O) - FALSE + TRUE FALSE TSPC_BAP_92_5 Initiating Periodic Advertising Sync Transfer for Local Periodic Advertising (C.1) - FALSE + TRUE FALSE TSPC_BAP_92_6 Initiating Periodic Advertising Sync Transfer for Remote Periodic Advertising (C.1) - FALSE + TRUE FALSE From c2c4e9ca1f4083e06fbd39773f11436ff3b2bc21 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Thu, 12 Sep 2024 11:44:06 +0200 Subject: [PATCH 02/32] doc/btp_hap: add HAS Client commands and events --- doc/btp_hap.txt | 105 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/doc/btp_hap.txt b/doc/btp_hap.txt index 84c0f71cb2..585b4dafc4 100644 --- a/doc/btp_hap.txt +++ b/doc/btp_hap.txt @@ -111,6 +111,77 @@ Commands and responses: (HAUC) discovery result event. In case of an error, the error response will be returned. + Opcode 0x09: HAP Read Presets + + Controller Index: + Command parameters: Address_Type (1 octet) + Address (6 octets) + Start_Index (1 octet) + Num_Presets (1 octet) + Response parameters: + + TODO: how do we get the results? + + This command is used to read the selected Presets. + If called with a Preset Index of 0, it will de-select the Active Preset. + + In case of an error, the error response will be returned. + + Opcode 0x0A: HAP Write Preset Name + + Controller Index: + Command parameters: Address_Type (1 octet) + Address (6 octets) + Preset Index (1 octet) + Name Length (1 octet) + Name ( octets) + Response parameters: + + Name shall be a UTF-8 encoded string. + Name Length holds the number of bytes in the UTF-8 encoded name. + + This command is used to change the Name of a Preset. + + In case of an error, the error response will be returned. + + Opcode 0x0B: HAP Set Active Preset + + Controller Index: + Command parameters: Address_Type (1 octet) + Address (6 octets) + Preset_Index (1 octet) + Synchronized_Locally (1) + Response parameters: + + This command is used to set the Active Preset. + If called with a Preset Index of 0, it will de-select the Active Preset. + + In case of an error, the error response will be returned. + + Opcode 0x0C: HAP Set Next Preset + + Controller Index: + Command parameters: Address_Type (1 octet) + Address (6 octets) + Synchronized_Locally (1) + Response parameters: + + This command is used to set the Active Preset. + + In case of an error, the error response will be returned. + + Opcode 0x0C: HAP Set Previous Preset + + Controller Index: + Command parameters: Address_Type (1 octet) + Address (6 octets) + Synchronized_Locally (1) + Response parameters: + + This command is used to set the Active Preset. + + In case of an error, the error response will be returned. + Events: Opcode 0x80 - Immediate Alert Client (IAC) discovery result @@ -133,3 +204,37 @@ Events: Valid Type values: 0x00 = Binaural Hearing Aid 0x01 = Monaural Hearing Aid 0x02 = Banded Hearing Aid + + Opcode 0x82 - Hearing Aid Preset Read event + Controller Index: + Event parameters: Address_Type (1 octet) + Address (6 octets) + Preset_Index (1 octet) + Properties (1 octet) + Name_Length (1 octet) + Name ( octets) + + Properties: bit 0: The name of the preset is writable + bit 1: The preset is available + + Name shall be a UTF-8 encoded string. + Name Length holds the number of bytes in the UTF-8 encoded name. + + Opcode 0x83 - Hearing Aid Preset Changed event + Controller Index: + Event parameters: Address_Type (1 octet) + Address (6 octets) + Change_Id (1 octet) + Is_Last (1 octet) + Preset_Index (1 octet) + Prev_Index (1 octet) - for Generic Update + Properties (1 octet) - for Generic Update + Name_Length (1 octet) - for Generic Update + Name ( octets) - for Generic Update + + Change_Id values: 0x00 = Generic Update + 0x01 = Preset Record Deleted + 0x02 = Preset Record Available + 0x03 = Preset Record Unavailable + + From bdb937de502ac49a0a7b34a7d6baf4336f13b610 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Thu, 12 Sep 2024 13:39:04 +0200 Subject: [PATCH 03/32] pybtp/defs: add HAS Client commands and events --- autopts/pybtp/btp/hap.py | 110 +++++++++++++++++++++++++++++++++++++++ autopts/pybtp/defs.py | 7 +++ 2 files changed, 117 insertions(+) diff --git a/autopts/pybtp/btp/hap.py b/autopts/pybtp/btp/hap.py index ae83b435d1..0c41d165ee 100644 --- a/autopts/pybtp/btp/hap.py +++ b/autopts/pybtp/btp/hap.py @@ -57,6 +57,21 @@ def address_to_ba(bd_addr_type=None, bd_addr=None): 'hauc_discover': (defs.BTP_SERVICE_ID_HAP, defs.HAP_HAUC_DISCOVER, CONTROLLER_INDEX), + 'hap_read_presets': (defs.BTP_SERVICE_ID_HAP, + defs.HAP_READ_PRESETS, + CONTROLLER_INDEX), + 'hap_write_preset_name': (defs.BTP_SERVICE_ID_HAP, + defs.HAP_WRITE_PRESET_NAME, + CONTROLLER_INDEX), + 'hap_set_active_preset': (defs.BTP_SERVICE_ID_HAP, + defs.HAP_SET_ACTIVE_PRESET, + CONTROLLER_INDEX), + 'hap_set_next_preset': (defs.BTP_SERVICE_ID_HAP, + defs.HAP_SET_NEXT_PRESET, + CONTROLLER_INDEX), + 'hap_set_previous_preset': (defs.BTP_SERVICE_ID_HAP, + defs.HAP_SET_PREVIOUS_PRESET, + CONTROLLER_INDEX), } def hap_command_rsp_succ(timeout=20.0, exp_op=None): @@ -146,6 +161,73 @@ def hap_hauc_discover(bd_addr_type=None, bd_addr=None): hap_command_rsp_succ() + +def hap_read_presets(start_index, num_presets, bd_addr_type=None, bd_addr=None): + logging.debug(f"{hap_read_presets.__name__}, start_index {start_index}, num_presets {num_presets}") + + data = address_to_ba(bd_addr_type, bd_addr) + data += struct.pack('B', start_index) + data += struct.pack('B', num_presets) + + iutctl = get_iut() + iutctl.btp_socket.send(*HAP['hap_read_presets'], data=data) + + hap_command_rsp_succ() + + +def hap_write_preset_name(index, name, bd_addr_type=None, bd_addr=None): + logging.debug(f"{hap_write_preset_name.__name__}, index {index}, name {name}") + encoded_name = name.encode() + size = len(encoded_name) + + data = address_to_ba(bd_addr_type, bd_addr) + data += struct.pack('B', index) + data += struct.pack('B', size) + data += encoded_name + + iutctl = get_iut() + iutctl.btp_socket.send(*HAP['hap_write_preset_name'], data=data) + + hap_command_rsp_succ() + + +def hap_set_active_preset(index, synchronize_locally=0, bd_addr_type=None, bd_addr=None): + logging.debug(f"{hap_set_active_preset.__name__}, index {index}, synchronize_locally {synchronize_locally}") + + data = address_to_ba(bd_addr_type, bd_addr) + data += struct.pack('B', index) + data += struct.pack('B', synchronize_locally) + + iutctl = get_iut() + iutctl.btp_socket.send(*HAP['hap_set_active_preset'], data=data) + + hap_command_rsp_succ() + + +def hap_set_next_preset(synchronize_locally=0, bd_addr_type=None, bd_addr=None): + logging.debug(f"{hap_set_next_preset.__name__}, synchronize_locally {synchronize_locally}") + + data = address_to_ba(bd_addr_type, bd_addr) + data += struct.pack('B', synchronize_locally) + + iutctl = get_iut() + iutctl.btp_socket.send(*HAP['hap_set_next_preset'], data=data) + + hap_command_rsp_succ() + + +def hap_set_previous_preset(synchronize_locally=0, bd_addr_type=None, bd_addr=None): + logging.debug(f"{hap_set_previous_preset.__name__}, synchronize_locally {synchronize_locally}") + + data = address_to_ba(bd_addr_type, bd_addr) + data += struct.pack('B', synchronize_locally) + + iutctl = get_iut() + iutctl.btp_socket.send(*HAP['hap_set_previous_preset'], data=data) + + hap_command_rsp_succ() + + def hap_ev_iac_discovery_complete_(hap, data, data_len): logging.debug("%s %r", hap_ev_iac_discovery_complete_.__name__, data) @@ -186,7 +268,35 @@ def hap_ev_hauc_discovery_complete_(hap, data, data_len): hearing_aid_control_point_handle, active_preset_index_handle)) + +def hap_ev_preset_changed_(hap, data, data_len): + logging.debug("%s %r", hap_ev_preset_changed_.__name__, data) + + fmt = ' Date: Thu, 12 Sep 2024 12:12:44 +0200 Subject: [PATCH 04/32] layers/hap: track HAUC discovery state --- autopts/ptsprojects/stack/layers/hap.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/autopts/ptsprojects/stack/layers/hap.py b/autopts/ptsprojects/stack/layers/hap.py index dbac24f0d1..85672bcd8f 100644 --- a/autopts/ptsprojects/stack/layers/hap.py +++ b/autopts/ptsprojects/stack/layers/hap.py @@ -23,6 +23,8 @@ def __init__(self): self.hearing_aid_features_handle = None self.hearing_aid_control_point_handle = None self.active_preset_index_handle = None + self.discover_started = False + self.discovery_completed = False def __init__(self): self.peers = {} @@ -73,3 +75,4 @@ def _ev_hauc_discovery_complete(self, addr_type, addr, status, peer.hearing_aid_features_handle = hearing_aid_features_handle peer.hearing_aid_control_point_handle = hearing_aid_control_point_handle peer.active_preset_index_handle = active_preset_index_handle + peer.discovery_completed = (status == defs.BTP_STATUS_SUCCESS) From 56e477657dfd8c0040657e7dee361580b00e540a Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Fri, 13 Sep 2024 19:04:25 +0200 Subject: [PATCH 05/32] layers/hap: store preset changed events --- autopts/ptsprojects/stack/layers/hap.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/autopts/ptsprojects/stack/layers/hap.py b/autopts/ptsprojects/stack/layers/hap.py index 85672bcd8f..34c9926c4e 100644 --- a/autopts/ptsprojects/stack/layers/hap.py +++ b/autopts/ptsprojects/stack/layers/hap.py @@ -31,6 +31,7 @@ def __init__(self): self.event_queues = { defs.HAP_EV_IAC_DISCOVERY_COMPLETE: [], defs.HAP_EV_HAUC_DISCOVERY_COMPLETE: [], + defs.HAP_EV_PRESET_CHANGED: [], } self.event_handlers = { defs.HAP_EV_HAUC_DISCOVERY_COMPLETE: self._ev_hauc_discovery_complete, @@ -76,3 +77,10 @@ def _ev_hauc_discovery_complete(self, addr_type, addr, status, peer.hearing_aid_control_point_handle = hearing_aid_control_point_handle peer.active_preset_index_handle = active_preset_index_handle peer.discovery_completed = (status == defs.BTP_STATUS_SUCCESS) + + def wait_preset_changed_ev(self, addr_type, addr, timeout, change_id, remove=True): + return wait_for_queue_event( + self.event_queues[defs.HAP_EV_PRESET_CHANGED], + lambda _addr_type, _addr, _change_id, *_: + (addr_type, addr, change_id) == (_addr_type, _addr, _change_id), + timeout, remove) From a9ba56171e1e9f7a3566f22a79116ef6a9bfbd51 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Tue, 10 Sep 2024 16:26:55 +0200 Subject: [PATCH 06/32] wid/hap.py: use CAP Unicast client to configure Streaming state --- autopts/wid/hap.py | 94 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 66 insertions(+), 28 deletions(-) diff --git a/autopts/wid/hap.py b/autopts/wid/hap.py index 1b4628882d..557f050beb 100644 --- a/autopts/wid/hap.py +++ b/autopts/wid/hap.py @@ -14,16 +14,34 @@ # import logging +from argparse import Namespace from autopts.pybtp import btp from autopts.ptsprojects.stack import get_stack from autopts.ptsprojects.testcase import MMI +from autopts.pybtp.defs import AUDIO_METADATA_STREAMING_AUDIO_CONTEXTS from autopts.pybtp.types import * from autopts.pybtp.btp.btp import pts_addr_get, pts_addr_type_get from autopts.wid import generic_wid_hdl log = logging.debug +def create_default_config(): + return Namespace(addr=pts_addr_get(), + addr_type=pts_addr_type_get(), + vid=0x0000, + cid=0x0000, + coding_format=0x06, + frames_per_sdu=0x01, + audio_locations=0x01, + cig_id=0x00, + cis_id=0x00, + presentation_delay=40000, + qos_config=None, + codec_set_name=None, + codec_ltvs=None, + metadata_ltvs=None, + mono=None) def hap_wid_hdl(wid, description, test_case_name): log(f'{hap_wid_hdl.__name__}, {wid}, {description}, {test_case_name}') @@ -86,13 +104,30 @@ def hdl_wid_482(_: WIDParams): addr_type = pts_addr_type_get() stack = get_stack() - # TODO: Rewrite this test to use CAP API instead - audio_dir = AudioDir.SINK coding_format = 0x06 audio_location_list = [defs.PACS_AUDIO_LOCATION_FRONT_LEFT, defs.PACS_AUDIO_LOCATION_FRONT_RIGHT] ase_ids = [] + default_config = create_default_config() + default_config.codec_set_name = '24_1' + default_config.qos_set_name = '24_1_1' + default_config.metadata_ltvs = struct.pack(' Date: Mon, 9 Sep 2024 08:15:31 +0200 Subject: [PATCH 07/32] wid/hap: handle both HAS and IAS discovery in hdl_wid_20103 --- autopts/wid/hap.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/autopts/wid/hap.py b/autopts/wid/hap.py index 557f050beb..35f6c41ac7 100644 --- a/autopts/wid/hap.py +++ b/autopts/wid/hap.py @@ -225,9 +225,9 @@ def hdl_wid_20100(_: WIDParams): return True -def hdl_wid_20103(_: WIDParams): +def hdl_wid_20103(params: WIDParams): """ - Please take action to discover the Alert Level characteristic from the Immediate Alert. + Please take action to discover the X Control Point characteristic from the Y. Discover the primary service if needed. Description: Verify that the Implementation Under Test (IUT) can send Discover All Characteristics command. """ @@ -235,8 +235,13 @@ def hdl_wid_20103(_: WIDParams): addr_type = pts_addr_type_get() stack = get_stack() - btp.hap_iac_discover(addr_type, addr) - stack.hap.wait_iac_discovery_complete_ev(addr_type, addr, 30) + # Pick Service to discover by description text + if 'Alert Level' in params.description: + btp.hap_iac_discover(addr_type, addr) + stack.hap.wait_iac_discovery_complete_ev(addr_type, addr, 30) + else: + btp.hap_hauc_discover(addr_type, addr) + stack.hap.wait_hauc_discovery_complete_ev(addr_type, addr, 30) return True From 91a061fa35d7260a670653895f85f7287d2efdf3 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Tue, 17 Sep 2024 14:28:30 +0200 Subject: [PATCH 08/32] wid/hap: add missing window handler --- autopts/wid/hap.py | 381 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 362 insertions(+), 19 deletions(-) diff --git a/autopts/wid/hap.py b/autopts/wid/hap.py index 35f6c41ac7..25266bf848 100644 --- a/autopts/wid/hap.py +++ b/autopts/wid/hap.py @@ -14,6 +14,7 @@ # import logging +import re from argparse import Namespace from autopts.pybtp import btp @@ -21,7 +22,7 @@ from autopts.ptsprojects.testcase import MMI from autopts.pybtp.defs import AUDIO_METADATA_STREAMING_AUDIO_CONTEXTS from autopts.pybtp.types import * -from autopts.pybtp.btp.btp import pts_addr_get, pts_addr_type_get +from autopts.pybtp.btp.btp import pts_addr_get, pts_addr_type_get, lt2_addr_get, lt2_addr_type_get from autopts.wid import generic_wid_hdl log = logging.debug @@ -47,8 +48,258 @@ def hap_wid_hdl(wid, description, test_case_name): log(f'{hap_wid_hdl.__name__}, {wid}, {description}, {test_case_name}') return generic_wid_hdl(wid, description, test_case_name, [__name__]) +def hap_start_hap_discovery(addr_type, addr): + stack = get_stack() + peer = stack.hap.get_peer(addr_type, addr) + if peer.discover_started: + log('Skip HAP discovery, discovery started before') + return + + peer.discover_started = True + btp.hap_hauc_discover(addr_type, addr) + stack.hap.wait_hauc_discovery_complete_ev(addr_type, addr, 30) + # wid handlers section begin +def hdl_wid_462(params: WIDParams): + """ + Please write Set Active Preset opcode with index: X. + """ + + if params.test_case_name.endswith('LT2'): + addr = lt2_addr_get() + addr_type = lt2_addr_type_get() + else: + addr = pts_addr_get() + addr_type = pts_addr_type_get() + + preset_index = int(re.search(r'\d+', params.description).group()) + btp.hap_set_active_preset(preset_index, 0, addr_type, addr) + + return True + + +def hdl_wid_463(params: WIDParams): + """ + Please write Set Next Preset opcode + """ + + if params.test_case_name.endswith('LT2'): + addr = lt2_addr_get() + addr_type = lt2_addr_type_get() + else: + addr = pts_addr_get() + addr_type = pts_addr_type_get() + + btp.hap_set_next_preset(0, addr_type, addr) + + return True + + +def hdl_wid_464(params: WIDParams): + """ + Please write Set Previous Preset opcode + """ + + if params.test_case_name.endswith('LT2'): + addr = lt2_addr_get() + addr_type = lt2_addr_type_get() + else: + addr = pts_addr_get() + addr_type = pts_addr_type_get() + + btp.hap_set_previous_preset(0, addr_type, addr) + + return True + + +def hdl_wid_465(params: WIDParams): + """ + Please write Read Preset opcode with index 0x01 and num presets to 0xff. + """ + + if params.test_case_name.endswith('LT2'): + addr = lt2_addr_get() + addr_type = lt2_addr_type_get() + else: + addr = pts_addr_get() + addr_type = pts_addr_type_get() + + numbers = re.findall(r'0x[0-9a-fA-F]+', params.description) + start_index = int(numbers[0], 16) + num_presets = int(numbers[1], 16) + btp.hap_read_presets(start_index, num_presets, addr_type, addr) + + return True + + +def hdl_wid_466(params: WIDParams): + """ + Please write Read Preset Index opcode with index: 2, numPresets: 1. + """ + + if params.test_case_name.endswith('LT2'): + addr = lt2_addr_get() + addr_type = lt2_addr_type_get() + else: + addr = pts_addr_get() + addr_type = pts_addr_type_get() + + numbers = re.findall(r'\d+', params.description) + start_index = int(numbers[0]) + num_presets = int(numbers[0]) + btp.hap_read_presets(start_index, num_presets, addr_type, addr) + + return True + +def hdl_wid_467(params: WIDParams): + """ + Please confirm that new preset record was added to IUT's internal list. + """ + + if params.test_case_name.endswith('LT2'): + addr = lt2_addr_get() + addr_type = lt2_addr_type_get() + else: + addr = pts_addr_get() + addr_type = pts_addr_type_get() + + stack = get_stack() + preset_change_received = stack.hap.wait_preset_changed_ev(addr_type, addr, 0, 30) + + return preset_change_received + + +def hdl_wid_468(params: WIDParams): + """ + Please update Index: 2 with new name in "New Preset Name" + """ + + if params.test_case_name.endswith('LT2'): + addr = lt2_addr_get() + addr_type = lt2_addr_type_get() + else: + addr = pts_addr_get() + addr_type = pts_addr_type_get() + + match = re.search(r'Index:\s*(\d+)\s*with new name in\s*"([^"]+)"', params.description) + if not match: + return False + + preset_index = int(match.group(1)) + name = match.group(2) + btp.hap_write_preset_name(preset_index, name, addr_type, addr) + + return True + + +def hdl_wid_469(params: WIDParams): + """ + Please write Set Active Preset Synchronized Locally opcode with index: X. + """ + + if params.test_case_name.endswith('LT2'): + addr = lt2_addr_get() + addr_type = lt2_addr_type_get() + else: + addr = pts_addr_get() + addr_type = pts_addr_type_get() + + preset_index = int(re.search(r'\d+', params.description).group()) + btp.hap_set_active_preset(preset_index, 1, addr_type, addr) + + return True + + +def hdl_wid_470(params: WIDParams): + """ + Please write Set Next Preset Synchronized Locally opcode + """ + + if params.test_case_name.endswith('LT2'): + addr = lt2_addr_get() + addr_type = lt2_addr_type_get() + else: + addr = pts_addr_get() + addr_type = pts_addr_type_get() + + btp.hap_set_next_preset(1, addr_type, addr) + + return True + + +def hdl_wid_471(params: WIDParams): + """ + Please write Set Previous Preset Synchronized Locally opcode. + """ + + if params.test_case_name.endswith('LT2'): + addr = lt2_addr_get() + addr_type = lt2_addr_type_get() + else: + addr = pts_addr_get() + addr_type = pts_addr_type_get() + + btp.hap_set_previous_preset(1, addr_type, addr) + + return True + + +def hdl_wid_472(params: WIDParams): + """ + Please write Set Active Preset opcode with index: 2. Do not expect to receive the message + """ + + # similar to 'Please write Set Active Preset opcode with index: X' + return hdl_wid_462(params) + + +def hdl_wid_473(params: WIDParams): + """ + Please update Index: 1 with new name in random 40 characters + """ + + if params.test_case_name.endswith('LT2'): + addr = lt2_addr_get() + addr_type = lt2_addr_type_get() + else: + addr = pts_addr_get() + addr_type = pts_addr_type_get() + + # Extract index and new name + match = re.search(r'Index: (\d+) with new name in random (\d+) characters', params.description) + if not match: + return False + + preset_index = int(match.group(1)) + num_characters = int(match.group(2)) + name = 'r' * num_characters + btp.hap_write_preset_name(preset_index, name, addr_type, addr) + + return True + + +def hdl_wid_474(_: WIDParams): + """ + Please click OK when both lower testers are performed operation (MMI poped up both Lower testers) + """ + + # Synchronized in ptsproject/hap.py + + return True + +def hdl_wid_476(_: WIDParams): + """ + Please send exchange MTU command to the PTS with MTU size greater than 49. + """ + + # BTstack exchanges MTU before any GATT Client requests, so just discover something + addr = pts_addr_get() + addr_type = pts_addr_type_get() + hap_start_hap_discovery(addr_type, addr) + return True + + def hdl_wid_477(_: WIDParams): """ Please verify that the IUT starts alerting with a High Alert. @@ -59,6 +310,23 @@ def hdl_wid_477(_: WIDParams): return stack.ias.alert_lvl == 2 +def hdl_wid_478(params: WIDParams): + """ + Please write preset name to index: 1 with random string. + """ + if params.test_case_name.endswith('LT2'): + addr = lt2_addr_get() + addr_type = lt2_addr_type_get() + else: + addr = pts_addr_get() + addr_type = pts_addr_type_get() + + preset_index = int(re.search(r'\d+', params.description).group()) + name = "random string" + btp.hap_write_preset_name(preset_index, name, addr_type, addr) + + return True + def hdl_wid_479(_: WIDParams): """ @@ -78,15 +346,19 @@ def hdl_wid_480(_: WIDParams): return True -def hdl_wid_481(_: WIDParams): +def hdl_wid_481(params: WIDParams): """ Please read SIRK Characteristic. """ - stack = get_stack() - addr = pts_addr_get() - addr_type = pts_addr_type_get() + if params.test_case_name.endswith('LT2'): + addr = lt2_addr_get() + addr_type = lt2_addr_type_get() + else: + addr = pts_addr_get() + addr_type = pts_addr_type_get() # SIRK is read during CSIP discovery + stack = get_stack() btp.csip_discover(addr_type, addr) ev = stack.csip.wait_discovery_completed_ev(addr_type, addr, 30) @@ -198,6 +470,34 @@ def hdl_wid_489(_: WIDParams): return not ev is None +def hdl_wid_490(_: WIDParams): + """ + Please click OK after IUT discovered and configured. + """ + # no idea what this means, but we can click OK for sure + return True + + +def hdl_wid_491(_: WIDParams): + """ + Please update Index: 2 with new name in LT2. Do not expect IUT to send command to LT2. + """ + addr = lt2_addr_get() + addr_type = lt2_addr_type_get() + + # as we're not supposed to actually send this, the values don't matter + btp.hap_write_preset_name(2, "New Name", addr_type, addr) + + return True + + +def hdl_wid_493(_: WIDParams): + """ + Please click OK when IUT is ready to receive Preset Changed message + """ + return True + + def hdl_wid_20001(_: WIDParams): """ Please prepare IUT into a connectable mode. @@ -209,15 +509,19 @@ def hdl_wid_20001(_: WIDParams): return True -def hdl_wid_20100(_: WIDParams): +def hdl_wid_20100(params: WIDParams): """ Please initiate a GATT connection to the PTS. Description: Verify that the Implementation Under Test (IUT) can initiate a GATT connect request to the PTS. """ - addr = pts_addr_get() - addr_type = pts_addr_type_get() - stack = get_stack() + if params.test_case_name.endswith('LT2'): + addr = lt2_addr_get() + addr_type = lt2_addr_type_get() + else: + addr = pts_addr_get() + addr_type = pts_addr_type_get() + stack = get_stack() btp.gap_conn(addr, addr_type) stack.gap.wait_for_connection(timeout=10, addr=addr) stack.gap.gap_wait_for_sec_lvl_change(level=2, timeout=30, addr=addr) @@ -240,23 +544,43 @@ def hdl_wid_20103(params: WIDParams): btp.hap_iac_discover(addr_type, addr) stack.hap.wait_iac_discovery_complete_ev(addr_type, addr, 30) else: - btp.hap_hauc_discover(addr_type, addr) - stack.hap.wait_hauc_discovery_complete_ev(addr_type, addr, 30) + hap_start_hap_discovery(addr_type, addr) + return True + + +def hdl_wid_20105(params: WIDParams): + """ + Please write to Client Characteristic Configuration Descriptor of Hearing Aid Preset + Control Point characteristic to enable indication. + """ + if params.test_case_name.endswith('LT2'): + addr = lt2_addr_get() + addr_type = lt2_addr_type_get() + else: + addr = pts_addr_get() + addr_type = pts_addr_type_get() + hap_start_hap_discovery(addr_type, addr) return True -def hdl_wid_20106(_: WIDParams): +def hdl_wid_20106(params: WIDParams): """ Please write to Client Characteristic Configuration Descriptor of ASE Control Point characteristic to enable notification. """ - addr = pts_addr_get() - addr_type = pts_addr_type_get() - stack = get_stack() + if params.test_case_name.endswith('LT2'): + addr = lt2_addr_get() + addr_type = lt2_addr_type_get() + else: + addr = pts_addr_get() + addr_type = pts_addr_type_get() + stack = get_stack() peer = stack.bap.get_peer(addr_type, addr) if peer.discovery_completed: + log('Skip BAP discovery, discovery completed before') + # Skip if discovery has been done already return True @@ -265,6 +589,28 @@ def hdl_wid_20106(_: WIDParams): return True +def hdl_wid_20107(params: WIDParams): + """ + Please send Read Request to read X characteristic with handle = Y. + """ + addr = pts_addr_get() + addr_type = pts_addr_type_get() + stack = get_stack() + + MMI.reset() + MMI.parse_description(params.description) + + value_handle = MMI.args[0] + + if not value_handle: + logging.debug("parsing error") + return False + + # Read Characteristic Value and wait for response + btp.gattc_read(addr_type, addr, value_handle) + btp.gattc_read_rsp() + + return True def hdl_wid_20116(_: WIDParams): """ @@ -273,11 +619,8 @@ def hdl_wid_20116(_: WIDParams): """ addr = pts_addr_get() addr_type = pts_addr_type_get() - stack = get_stack() - - btp.hap_hauc_discover(addr_type, addr) - stack.hap.wait_hauc_discovery_complete_ev(addr_type, addr, 30) + hap_start_hap_discovery(addr_type, addr) return True From e563ce2d43eab3282d8bab40d561f6cb8821010b Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Thu, 19 Sep 2024 15:41:30 +0200 Subject: [PATCH 09/32] wid/hap: add wid handler for eatt --- autopts/wid/hap.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/autopts/wid/hap.py b/autopts/wid/hap.py index 25266bf848..525fce1f46 100644 --- a/autopts/wid/hap.py +++ b/autopts/wid/hap.py @@ -647,6 +647,21 @@ def hdl_wid_20128(_: WIDParams): return True +def hdl_wid_20137(params: WIDParams): + """ + Please initiate an L2CAP Credit Based Connection to the PTS. + """ + if params.test_case_name.endswith('LT2'): + addr = lt2_addr_get() + addr_type = lt2_addr_type_get() + else: + addr = pts_addr_get() + addr_type = pts_addr_type_get() + + btp.gatt.eatt_conn(addr, addr_type, 5) + return True + + def hdl_wid_20144(_: WIDParams): """ Please click Yes if IUT support Write Command(without response), otherwise click No. From c0dd70bbcaf69cce382b9ab18a47a5f2a57b9a1a Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Mon, 21 Oct 2024 11:00:42 +0200 Subject: [PATCH 10/32] doc/btp_hap: improve documentation --- doc/btp_hap.txt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/doc/btp_hap.txt b/doc/btp_hap.txt index 585b4dafc4..546339c3e8 100644 --- a/doc/btp_hap.txt +++ b/doc/btp_hap.txt @@ -120,10 +120,8 @@ Commands and responses: Num_Presets (1 octet) Response parameters: - TODO: how do we get the results? - This command is used to read the selected Presets. - If called with a Preset Index of 0, it will de-select the Active Preset. + Each preset is returned in a Hearing Aid Preset Read event. In case of an error, the error response will be returned. @@ -150,7 +148,7 @@ Commands and responses: Command parameters: Address_Type (1 octet) Address (6 octets) Preset_Index (1 octet) - Synchronized_Locally (1) + Synchronized_Locally (1 octet) Response parameters: This command is used to set the Active Preset. From 325aa978bae764b240406f97f434003f2bcd3964 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Mon, 8 Jul 2024 15:29:22 +0200 Subject: [PATCH 11/32] Add PBP --- autopts/ptsprojects/stack/layers/__init__.py | 1 + autopts/ptsprojects/stack/layers/pbp.py | 33 +++ autopts/ptsprojects/stack/stack.py | 8 + autopts/pybtp/btp/__init__.py | 1 + autopts/pybtp/btp/btp.py | 11 + autopts/pybtp/btp/pbp.py | 140 ++++++++++ autopts/pybtp/defs.py | 8 + autopts/wid/__init__.py | 1 + autopts/wid/pbp.py | 263 +++++++++++++++++++ doc/btp_pbp.txt | 77 ++++++ doc/overview.txt | 1 + 11 files changed, 544 insertions(+) create mode 100644 autopts/ptsprojects/stack/layers/pbp.py create mode 100644 autopts/pybtp/btp/pbp.py create mode 100644 autopts/wid/pbp.py create mode 100644 doc/btp_pbp.txt diff --git a/autopts/ptsprojects/stack/layers/__init__.py b/autopts/ptsprojects/stack/layers/__init__.py index adb4e1e374..4e6a23e041 100644 --- a/autopts/ptsprojects/stack/layers/__init__.py +++ b/autopts/ptsprojects/stack/layers/__init__.py @@ -40,4 +40,5 @@ from .gtbs import * from .tmap import * from .ots import * +from .pbp import * # GENERATOR append 1 diff --git a/autopts/ptsprojects/stack/layers/pbp.py b/autopts/ptsprojects/stack/layers/pbp.py new file mode 100644 index 0000000000..6ca5f254ab --- /dev/null +++ b/autopts/ptsprojects/stack/layers/pbp.py @@ -0,0 +1,33 @@ +# +# auto-pts - The Bluetooth PTS Automation Framework +# +# Copyright (c) 2024, BlueKitchen GmbH. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# + +from autopts.ptsprojects.stack.common import wait_for_queue_event +from autopts.pybtp import defs + + +class PBP: + def __init__(self): + self.event_queues = { + defs.PBP_EV_PUBLIC_BROADCAST_ANNOUNCEMENT_FOUND: [], + } + + def event_received(self, event_type, event_data): + self.event_queues[event_type].append(event_data) + + def wait_public_broadcast_event_found_ev(self, addr_type, addr, broadcast_name, timeout, remove=True): + return wait_for_queue_event( + self.event_queues[defs.PBP_EV_PUBLIC_BROADCAST_ANNOUNCEMENT_FOUND], + lambda ev: (addr_type, addr, broadcast_name) == (ev['addr_type'], ev['addr'], ev['broadcast_name']), + timeout, remove) diff --git a/autopts/ptsprojects/stack/stack.py b/autopts/ptsprojects/stack/stack.py index 74879f0338..b49aea84a1 100644 --- a/autopts/ptsprojects/stack/stack.py +++ b/autopts/ptsprojects/stack/stack.py @@ -52,6 +52,7 @@ "TBS": 1 << defs.BTP_SERVICE_ID_TBS, "TMAP": 1 << defs.BTP_SERVICE_ID_TMAP, "OTS": 1 << defs.BTP_SERVICE_ID_OTS, + "PBP": 1 << defs.BTP_SERVICE_ID_PBP, # GENERATOR append 1 } @@ -87,6 +88,7 @@ def __init__(self): self.gtbs = None self.tmap = None self.ots = None + self.pbp = None # GENERATOR append 2 def is_svc_supported(self, svc): @@ -186,6 +188,9 @@ def tmap_init(self): def ots_init(self): self.ots = OTS() + def pbp_init(self): + self.pbp = PBP() + # GENERATOR append 3 def cleanup(self): @@ -267,6 +272,9 @@ def cleanup(self): if self.ots: self.ots_init() + if self.pbp: + self.pbp_init() + # GENERATOR append 4 diff --git a/autopts/pybtp/btp/__init__.py b/autopts/pybtp/btp/__init__.py index e26371ba92..eee1fd0d30 100644 --- a/autopts/pybtp/btp/__init__.py +++ b/autopts/pybtp/btp/__init__.py @@ -45,4 +45,5 @@ from autopts.pybtp.btp.tbs import * from autopts.pybtp.btp.tmap import * from autopts.pybtp.btp.ots import * +from autopts.pybtp.btp.pbp import * # GENERATOR append 1 diff --git a/autopts/pybtp/btp/btp.py b/autopts/pybtp/btp/btp.py index c86d1cf3b9..fa7db4d78f 100644 --- a/autopts/pybtp/btp/btp.py +++ b/autopts/pybtp/btp/btp.py @@ -129,6 +129,8 @@ def read_supp_svcs(): defs.BTP_INDEX_NONE, defs.BTP_SERVICE_ID_TMAP), "ots_reg": (defs.BTP_SERVICE_ID_CORE, defs.CORE_REGISTER_SERVICE, defs.BTP_INDEX_NONE, defs.BTP_SERVICE_ID_OTS), + "pbp_reg": (defs.BTP_SERVICE_ID_CORE, defs.CORE_REGISTER_SERVICE, + defs.BTP_INDEX_NONE, defs.BTP_SERVICE_ID_PBP), # GENERATOR append 4 "read_supp_cmds": (defs.BTP_SERVICE_ID_CORE, defs.CORE_READ_SUPPORTED_COMMANDS, @@ -704,6 +706,13 @@ def core_reg_svc_ots(): iutctl.btp_socket.send_wait_rsp(*CORE['ots_reg']) +def core_reg_svc_pbp(): + logging.debug("%s", core_reg_svc_pbp.__name__) + + iutctl = get_iut() + iutctl.btp_socket.send_wait_rsp(*CORE['pbp_reg']) + + # GENERATOR append 1 def core_reg_svc_rsp_succ(): @@ -805,6 +814,7 @@ def init(get_iut_method): from .tbs import TBS_EV from .tmap import TMAP_EV from .ots import OTS_EV +from .pbp import PBP_EV # GENERATOR append 2 from autopts.pybtp.iutctl_common import set_event_handler @@ -844,6 +854,7 @@ def event_handler(hdr, data): defs.BTP_SERVICE_ID_TBS: (TBS_EV, stack.tbs), defs.BTP_SERVICE_ID_TMAP: (TMAP_EV, stack.tmap), defs.BTP_SERVICE_ID_OTS: (OTS_EV, stack.ots), + defs.BTP_SERVICE_ID_PBP: (PBP_EV, stack.pbp), # GENERATOR append 3 } diff --git a/autopts/pybtp/btp/pbp.py b/autopts/pybtp/btp/pbp.py new file mode 100644 index 0000000000..34af9545b5 --- /dev/null +++ b/autopts/pybtp/btp/pbp.py @@ -0,0 +1,140 @@ +# +# auto-pts - The Bluetooth PTS Automation Framework +# +# Copyright (c) 2024, BlueKitchen GmbH. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# + +import binascii +import logging +import struct + +from autopts.pybtp import defs +from autopts.pybtp.btp.btp import CONTROLLER_INDEX, get_iut_method as get_iut, \ + btp_hdr_check +from autopts.pybtp.types import BTPError + +log = logging.debug + +PBP = { + 'read_supported_cmds': (defs.BTP_SERVICE_ID_PBP, + defs.PBP_READ_SUPPORTED_COMMANDS, + CONTROLLER_INDEX), + 'set_public_broadcast_announcement': (defs.BTP_SERVICE_ID_PBP, + defs.PBP_SET_PUBLIC_BROADCAST_ANNOUNCEMENT, + CONTROLLER_INDEX), + 'set_broadcast_name': (defs.BTP_SERVICE_ID_PBP, + defs.PBP_SET_BROADCAST_NAME, + CONTROLLER_INDEX), + 'broadcast_scan_start': (defs.BTP_SERVICE_ID_PBP, + defs.PBP_BROADCAST_SCAN_START, + CONTROLLER_INDEX), + 'broadcast_scan_stop': (defs.BTP_SERVICE_ID_PBP, + defs.PBP_BROADCAST_SCAN_STOP, + CONTROLLER_INDEX), +} + + +def pbp_command_rsp_succ(timeout=20.0): + logging.debug("%s", pbp_command_rsp_succ.__name__) + + iutctl = get_iut() + + tuple_hdr, tuple_data = iutctl.btp_socket.read(timeout) + logging.debug("received %r %r", tuple_hdr, tuple_data) + + btp_hdr_check(tuple_hdr, defs.BTP_SERVICE_ID_PBP) + + return tuple_data + + +def pbp_set_public_broadcast_announcement(features, metadata): + logging.debug(f"{pbp_set_public_broadcast_announcement.__name__}") + + data = bytearray() + metadata_len = len(metadata) + data += struct.pack('BB', features, metadata_len) + + if metadata_len: + data += metadata + + iutctl = get_iut() + iutctl.btp_socket.send(*PBP['set_public_broadcast_announcement'], data=data) + + pbp_command_rsp_succ() + + +def pbp_set_broadcast_name(name): + logging.debug(f"{pbp_set_broadcast_name.__name__}") + + name_data = name.encode('utf-8') + data = bytearray() + data += struct.pack('B', len(name_data)) + data += name_data + + iutctl = get_iut() + iutctl.btp_socket.send(*PBP['set_broadcast_name'], data=data) + + pbp_command_rsp_succ() + + +def pbp_broadcast_scan_start(): + logging.debug(f"{pbp_broadcast_scan_start.__name__}") + + data = bytearray() + iutctl = get_iut() + iutctl.btp_socket.send(*PBP['broadcast_scan_start'], data=data) + + pbp_command_rsp_succ() + + +def pbp_broadcast_scan_stop(): + logging.debug(f"{pbp_broadcast_scan_stop.__name__}") + + data = bytearray() + iutctl = get_iut() + iutctl.btp_socket.send(*PBP['broadcast_scan_stop'], data=data) + + pbp_command_rsp_succ() + + +def pbp_ev_public_broadcast_announcement_found(pbp, data, data_len): + logging.debug('%s %r', pbp_ev_public_broadcast_announcement_found.__name__, data) + + fmt = ' + Command parameters: + Response parameters: (variable) + + Each bit in response is a flag indicating if command with + opcode matching bit number is supported. Bit set to 1 means + that command is supported. Bit 0 is reserved and shall always + be set to 0. If specific bit is not present in response (less + than required bytes received) it shall be assumed that command + is not supported. + + In case of an error, the error response will be returned. + + Opcode 0x02: Set Public Broadcast Announcement + + Controller Index: + Command parameters: Features (1 octet) + Metadata LTVs len (1 octet) + LTVs (varies) + + This command is used to set the Public Broadcast Announcement in broadcast advertisements + + In case of an error, the error response will be returned. + + Opcode 0x03: Set Broadcast Name + + Controller Index: + Command parameters: Name Length (1 octet) + Name ( octets) + + This command is used to set the Public Broadcast Announcement in broadcast advertisements + + In case of an error, the error response will be returned. + + Opcode 0x04 - Broadcast Scan Start + Controller Index: + Command parameters: + Response parameters: + + This command is used to start scanning for Public Broadcast Announcements. + In case of an error, the error status response will be returned. + In case of a success, the IUT continues processing the command + asynchronously. + + Opcode 0x05 - Broadcast Scan Stop + Controller Index: + Command parameters: + Response parameters: + + This command is used to stop scanning for Public Broadcast Announcements. + In case of an error, the error status response will be returned. + In case of a success, the IUT continues processing the command + asynchronously. + +Events: + Opcode 0x80 - Public Broadcast Announcement Found event + + Controller Index: + Event parameters: Address_Type (1 octet) + Address (6 octets) + Broadcast_ID (3 octets) + Advertiser_SID (1 octet) + PA_Interval (2 octets) + PBA_Features (1 octet) + Broadcast_Name_Len (1 octet) + Broadcast_Name ( octets) + + This event returns info from scanned Public Broadcast Announcement. diff --git a/doc/overview.txt b/doc/overview.txt index 55771421ad..1f39842870 100644 --- a/doc/overview.txt +++ b/doc/overview.txt @@ -114,4 +114,5 @@ ID Name 27 TBS Service 28 TMAP Service 29 OTS Service + 30 PBP Service # GENERATOR append 1 From ecca549e4cf60219ba67dc4f29f64937f72e8d67 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Tue, 22 Oct 2024 10:39:48 +0200 Subject: [PATCH 12/32] Added python venv to gitignore Added venv and .venv which are common names for python virtual environments to the gitignore. Signed-off-by: Emil Gydesen --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index ac1205fce5..494da60bb6 100755 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,6 @@ */client_secret.json */credentials.json autopts/bot/config.py + +venv +.venv From 0d872eebec8aca3b73569751ac584a4c325cc142 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Tue, 22 Oct 2024 10:42:16 +0200 Subject: [PATCH 13/32] Add .vscode to gitignore Added .vscode to gitignore so that local editor settings are not pushed to the repo. Signed-off-by: Emil Gydesen --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 494da60bb6..67a554c48d 100755 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,5 @@ autopts/bot/config.py venv .venv + +.vscode From 9a1b43544f0f5fd3994d09778f7b94632517b99b Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 24 Oct 2024 20:13:43 +0200 Subject: [PATCH 14/32] Add tmp to gitignore The tmp directory is creating during manual testing and should never be pushed. Signed-off-by: Emil Gydesen --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 67a554c48d..7db58f9f01 100755 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ *~ *.pyc *.log +tmp *.xlsx *.zip From c233a511d5dd12c4a2866c839869212eb05b23ae Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 24 Oct 2024 08:54:49 +0200 Subject: [PATCH 15/32] wid: tmap: Use raw string for regex Fix following: autopts/wid/tmap.py:718: SyntaxWarning: invalid escape sequence '\d' --- autopts/wid/tmap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autopts/wid/tmap.py b/autopts/wid/tmap.py index abdd8917e8..767f59368a 100644 --- a/autopts/wid/tmap.py +++ b/autopts/wid/tmap.py @@ -715,7 +715,7 @@ def hdl_wid_2004(params: WIDParams): """ Please confirm that 6 digit number is matched with [passkey]. """ - pattern = '[\d]{6}' + pattern = r'[\d]{6}' passkey = re.search(pattern, params.description)[0] stack = get_stack() bd_addr = btp.pts_addr_get() From 7e33c059df24ccfb843891aec3c19289d2c3cdb1 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 25 Oct 2024 16:48:15 +0200 Subject: [PATCH 16/32] zephyr: mesh: Fix missing MBTM and DFUM profiles This was due to bug in Qualification Workspace. --- .../zephyr/zephyr-master/zephyr-master.pqw6 | 574 ++++++++++++++++++ 1 file changed, 574 insertions(+) diff --git a/autopts/workspaces/zephyr/zephyr-master/zephyr-master.pqw6 b/autopts/workspaces/zephyr/zephyr-master/zephyr-master.pqw6 index 14c1546f5f..a88530b908 100755 --- a/autopts/workspaces/zephyr/zephyr-master/zephyr-master.pqw6 +++ b/autopts/workspaces/zephyr/zephyr-master/zephyr-master.pqw6 @@ -9271,6 +9271,320 @@ + + + DFUM + + + + TSPC_DFUM_ALL + Enables all test cases when set. + FALSE + FALSE + + + TSPC_DFUM_0_1 + Mesh Device Firmware Update Model v1.0 (M) + TRUE + TRUE + + + TSPC_DFUM_3_1 + Firmware Update Server model (O) + TRUE + FALSE + + + TSPC_DFUM_3_2 + Firmware Distribution Server model (C.1) + TRUE + FALSE + + + TSPC_DFUM_3_3 + Firmware Update Client model (O) + TRUE + FALSE + + + TSPC_DFUM_3_4 + Firmware Distribution Client model (C.1) + FALSE + FALSE + + + TSPC_DFUM_10_1 + BLOB Transfer Server model (M) + TRUE + TRUE + + + TSPC_DFUM_11_1 + Pull BLOB Transfer Mode (C.1) + TRUE + FALSE + + + TSPC_DFUM_11_2 + Push BLOB Transfer Mode (C.2) + TRUE + FALSE + + + TSPC_DFUM_20_1 + BLOB Transfer Server model (M) + TRUE + TRUE + + + TSPC_DFUM_21_1 + Pull BLOB Transfer Mode (C.1) + TRUE + FALSE + + + TSPC_DFUM_21_2 + Push BLOB Transfer Mode (C.2) + TRUE + FALSE + + + TSPC_DFUM_22_1 + Store Firmware OOB procedure (O) + TRUE + FALSE + + + TSPC_DFUM_22_2 + Firmware Retrieval Over HTTPS procedure (C.1) + FALSE + FALSE + + + TSPC_DFUM_22_3 + Multiple Firmware Image Support (O) + TRUE + FALSE + + + TSPC_DFUM_30_1 + BLOB Transfer Client model (M) + TRUE + TRUE + + + TSPC_DFUM_40_1 + BLOB Transfer Client model (M) + FALSE + TRUE + + + TSPC_DFUM_41_1 + Upload Firmware OOB procedure (O) + FALSE + FALSE + + + TSPC_ALL + Enables all test cases when set. + FALSE + FALSE + + + + + DFUM + 1.0 + + + TSPX_bd_addr_iut + The unique 48-bit Bluetooth device address (BD_ADDR) of the IUT. This was filled in during workspace creation. + OCTETSTRING + 000000000000 + + + TSPX_time_guard + The time in milliseconds, to break PTS from waiting for a required event, if time guard is used by the test case. (Default: 300000) + INTEGER + 300000 + + + TSPX_use_implicit_send + Whether to receive a message via Implicit Send when an action or attention is needed by test operator. (Default: TRUE) + BOOLEAN + TRUE + + + TSPX_tester_database_file + Location of SIG database file. (Default: C:\Program Files\Bluetooth SIG\Bluetooth PTS\Data\SIGDatabase\PTS_SMPP_db.xml) + IA5STRING + C:\Program Files\Bluetooth SIG\Bluetooth PTS\Data\SIGDatabase\PTS_SMPP_db.xml + + + TSPX_mtu_size + MTU size. (Default: 23) + INTEGER + 23 + + + TSPX_delete_link_key + Whether to delete link key or not. (Default: FALSE) + BOOLEAN + FALSE + + + TSPX_delete_ltk + Whether to delete Long Term Key or not. (Default: FALSE) + BOOLEAN + FALSE + + + TSPX_security_enabled + Whether to set security for the test suite. (Default: FALSE) + BOOLEAN + FALSE + + + TSPX_iut_setup_att_over_br_edr + IUT can optionally test ATT over BR/EDR connection when this flag is set when applicable. (Default: FALSE) + BOOLEAN + FALSE + + + TSPX_scan_interval + The scan interval value N*0.625ms. Default is setto fast scan interval.(Default: 30) + INTEGER + 30 + + + TSPX_scan_window + The scan window value N*0.625ms. Default is set to fast scan window.(Default: 30) + INTEGER + 30 + + + TSPX_scan_filter + The scan filter setting to allow accept filter accept list only device.(Default: 0 - Fileter none) + OCTETSTRING + 00 + + + TSPX_advertising_interval_min + The minimum advertising interval value N*0.625ms. PTS will using this value to set advertising parameters.(Default: 160) + INTEGER + 160 + + + TSPX_advertising_interval_max + The maximum advertising interval value N*0.625ms. PTS will using this value to set advertising parameters.(Default: 160) + INTEGER + 160 + + + TSPX_tester_OOB_information + The 16-bit tester OOB information value. PTS will advertise using this value when in peripheral role.(Default: F87F) + OCTETSTRING + F87F + + + TSPX_device_uuid + used for mesh beacon. (Default: 001BDC0810210B0E0A0C000B0E0A0C00) + OCTETSTRING + 001BDC0810210B0E0A0C000B0E0A0C00 + + + TSPX_device_uuid2 + used for tester2 mesh beacon. (Default: 00000000000000000000000000000000) + OCTETSTRING + 00000000000000000000000000000000 + + + TSPX_use_pb_gatt_bearer + PB ADV or PB GATT bearer for PROT test cases. (Default: TRUE - PB-ADV) + BOOLEAN + FALSE + + + TSPX_iut_comp_data_page + The page number of the composition data (Default: 0) + INTEGER + 0 + + + TSPX_oob_state_change + Indicates if the IUT supports out-of-band triggered state changes. If set to TRUE, then the IUT supports Upper Tester commands to trigger a state change. (Default: FALSE) + BOOLEAN + FALSE + + + TSPX_enable_IUT_provisioner + Indicates if the IUT performs provisioning for client cases. If set to TRUE, PTS expects to get provisioned by the IUT. (Default: FALSE) + BOOLEAN + FALSE + + + TSPX_Procedure_Timeout + The time in seconds. (Default: 60) + INTEGER + 60 + + + TSPX_Client_BLOB_ID + Unique identifier for the BLOB being transferred by the BLOB Transfer Client IUT. (Default: 1) + OCTETSTRING + 1100000000000011 + + + TSPX_Client_BLOB_Data + BLOB being transferred by the IUT. + IA5STRING + + + + TSPX_TTL + TTL. (Default: 2) + INTEGER + 2 + + + TSPX_Server_Timeout_Base + Server Timeout Base state. (Default: 5) + INTEGER + 5 + + + TSPX_Firmware_ID + Firmware_ID used by device to varify firmware.(Default: 1) + OCTETSTRING + 11000011 + + + TSPX_Firmware_Metadata + Firmware metadata for the incoming firmware on the IUT. (Default: ) + OCTETSTRING + 1100000000000011 + + + TSPX_Firmware_Update_URI + URI used for test case execution. (Default: http://www.dummy.com) + IA5STRING + http://www.dummy.com + + + TSPX_New_Firmware_Image + Firmware being transferred by the IUT. + IA5STRING + + + + TSPX_Update_Firmware_Image_Index + Firmware Image Index value to identiy firmware used for testing. (Default: 0) + INTEGER + 0 + + + + DIS @@ -18894,6 +19208,266 @@ + + + MBTM + + + + TSPC_MBTM_ALL + Enables all test cases when set. + FALSE + FALSE + + + TSPC_MBTM_0_1 + Mesh Binary Large Object Transfer Model v1.0 (M) + TRUE + TRUE + + + TSPC_MBTM_3_1 + BLOB Transfer Server model (C.1) + TRUE + FALSE + + + TSPC_MBTM_3_2 + BLOB Transfer Client model (C.1) + TRUE + FALSE + + + TSPC_MBTM_10_1 + Pull BLOB Transfer Mode (C.1) + TRUE + FALSE + + + TSPC_MBTM_10_2 + Push BLOB Transfer Mode (C.1) + TRUE + FALSE + + + TSPC_MBTM_20_1 + Pull BLOB Transfer Mode (M) + TRUE + TRUE + + + TSPC_MBTM_20_2 + Push BLOB Transfer Mode (M) + TRUE + TRUE + + + TSPC_ALL + Enables all test cases when set. + FALSE + FALSE + + + + + MBTM + 1.0 + + + TSPX_bd_addr_iut + The unique 48-bit Bluetooth device address (BD_ADDR) of the IUT. This was filled in during workspace creation. + OCTETSTRING + 000000000000 + + + TSPX_time_guard + The time in milliseconds, to break PTS from waiting for a required event, if time guard is used by the test case. (Default: 300000) + INTEGER + 300000 + + + TSPX_use_implicit_send + Whether to receive a message via Implicit Send when an action or attention is needed by test operator. (Default: TRUE) + BOOLEAN + TRUE + + + TSPX_tester_database_file + Location of SIG database file. (Default: C:\Program Files\Bluetooth SIG\Bluetooth PTS\Data\SIGDatabase\PTS_SMPP_db.xml) + IA5STRING + C:\Program Files\Bluetooth SIG\Bluetooth PTS\Data\SIGDatabase\PTS_SMPP_db.xml + + + TSPX_mtu_size + MTU size. (Default: 23) + INTEGER + 23 + + + TSPX_delete_link_key + Whether to delete link key or not. (Default: FALSE) + BOOLEAN + FALSE + + + TSPX_delete_ltk + Whether to delete Long Term Key or not. (Default: FALSE) + BOOLEAN + FALSE + + + TSPX_security_enabled + Whether to set security for the test suite. (Default: FALSE) + BOOLEAN + FALSE + + + TSPX_iut_setup_att_over_br_edr + IUT can optionally test ATT over BR/EDR connection when this flag is set when applicable. (Default: FALSE) + BOOLEAN + FALSE + + + TSPX_scan_interval + The scan interval value N*0.625ms. Default is setto fast scan interval.(Default: 30) + INTEGER + 30 + + + TSPX_scan_window + The scan window value N*0.625ms. Default is set to fast scan window.(Default: 30) + INTEGER + 30 + + + TSPX_scan_filter + The scan filter setting to allow accept filter accept list only device.(Default: 0 - Fileter none) + OCTETSTRING + 00 + + + TSPX_advertising_interval_min + The minimum advertising interval value N*0.625ms. PTS will using this value to set advertising parameters.(Default: 160) + INTEGER + 160 + + + TSPX_advertising_interval_max + The maximum advertising interval value N*0.625ms. PTS will using this value to set advertising parameters.(Default: 160) + INTEGER + 160 + + + TSPX_tester_OOB_information + The 16-bit tester OOB information value. PTS will advertise using this value when in peripheral role.(Default: F87F) + OCTETSTRING + F87F + + + TSPX_device_uuid + used for mesh beacon. (Default: 001BDC0810210B0E0A0C000B0E0A0C00) + OCTETSTRING + 001BDC0810210B0E0A0C000B0E0A0C00 + + + TSPX_device_uuid2 + used for tester2 mesh beacon. (Default: 00000000000000000000000000000000) + OCTETSTRING + 00000000000000000000000000000000 + + + TSPX_use_pb_gatt_bearer + PB ADV or PB GATT bearer for PROT test cases. (Default: TRUE - PB-ADV) + BOOLEAN + FALSE + + + TSPX_iut_comp_data_page + The page number of the composition data (Default: 0) + INTEGER + 0 + + + TSPX_oob_state_change + Indicates if the IUT supports out-of-band triggered state changes. If set to TRUE, then the IUT supports Upper Tester commands to trigger a state change. (Default: FALSE) + BOOLEAN + FALSE + + + TSPX_enable_IUT_provisioner + Indicates if the IUT performs provisioning for client cases. If set to TRUE, PTS expects to get provisioned by the IUT. (Default: FALSE) + BOOLEAN + FALSE + + + TSPX_Procedure_Timeout + The time in seconds. (Default: 60) + INTEGER + 60 + + + TSPX_Client_BLOB_ID + Unique identifier for the BLOB being transferred by the BLOB Transfer Client IUT. (Default: 1) + OCTETSTRING + 1100000000000011 + + + TSPX_Client_BLOB_Data + BLOB being transferred by the IUT. + IA5STRING + + + + TSPX_Transfer_TTL + TTL. (Default: 3) + INTEGER + 3 + + + TSPX_Client_Timeout_Base + Client Timeout Base state. (Default: 5) + INTEGER + 4 + + + TSPX_Server_Timeout_Base + Server Timeout Base state. (Default: 5) + INTEGER + 5 + + + TSPX_Firmware_ID + Firmware_ID used by device to varify firmware.(Default: 1) + OCTETSTRING + 11000011 + + + TSPX_Firmware_Metadata + Firmware metadata for the incoming firmware on the IUT. (Default: ) + OCTETSTRING + 1100000000000011 + + + TSPX_Firmware_Update_URI + URI used for test case execution. (Default: http://www.dummy.com) + IA5STRING + http://www.dummy.com + + + TSPX_New_Firmware_Image + Firmware being transferred by the IUT. + IA5STRING + + + + TSPX_Update_Firmware_Image_Index + Firmware Image Index value to identiy firmware used for testing. (Default: 0) + INTEGER + 0 + + + + MCP From 8c10e1874895642fd3b478e7bab0af6c29f2a470 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Tue, 5 Nov 2024 14:54:59 +0100 Subject: [PATCH 17/32] csip: Add CSIP/CL/SP/BV-07-C to list of tests for CSIP discovery The test also requires discovery and was failing due to this. Re-arranged the list of tests to be in alphabetical order to make it easier to follow. Signed-off-by: Emil Gydesen --- autopts/wid/csip.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/autopts/wid/csip.py b/autopts/wid/csip.py index b362a635c3..bdc397f9b0 100644 --- a/autopts/wid/csip.py +++ b/autopts/wid/csip.py @@ -179,10 +179,11 @@ def hdl_wid_20100(params: WIDParams): stack.gap.wait_for_connection(timeout=10, addr=addr) stack.gap.gap_wait_for_sec_lvl_change(level=2, timeout=30, addr=addr) - if 'CSIP/CL/SP/BV-04-C' in params.test_case_name or\ + if 'CSIP/CL/SP/BV-03-C' in params.test_case_name or\ + 'CSIP/CL/SP/BV-04-C' in params.test_case_name or\ + 'CSIP/CL/SP/BV-07-C' in params.test_case_name or\ 'CSIP/CL/SPE/BI-01-C' in params.test_case_name or\ 'CSIP/CL/SPE/BI-02-C' in params.test_case_name or\ - 'CSIP/CL/SP/BV-03-C' in params.test_case_name or\ 'CSIP/CL/SPE/BI-03-C' in params.test_case_name: btp.csip_discover(addr_type, addr) ev = stack.csip.wait_sirk_ev(addr_type, addr, 30, remove=False) From 6a5f1054fd0bcbfe40945f4ebdd9e0090ef12442 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Tue, 5 Nov 2024 14:13:13 +0100 Subject: [PATCH 18/32] Redefine services as hex instead of decimal Redefine the btp service values from decimal to hexidecimal, so they are aligned with opcodes, indexes, etc. Signed-off-by: Emil Gydesen --- autopts/pybtp/defs.py | 60 +++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/autopts/pybtp/defs.py b/autopts/pybtp/defs.py index c802844c2d..23e07b761b 100644 --- a/autopts/pybtp/defs.py +++ b/autopts/pybtp/defs.py @@ -23,36 +23,36 @@ def BIT(bit): BTP_MTU = 1024 BTP_INDEX_NONE = 0xff -BTP_SERVICE_ID_CORE = 0 -BTP_SERVICE_ID_GAP = 1 -BTP_SERVICE_ID_GATT = 2 -BTP_SERVICE_ID_L2CAP = 3 -BTP_SERVICE_ID_MESH = 4 -BTP_SERVICE_ID_MMDL = 5 -BTP_SERVICE_ID_GATTC = 6 -BTP_SERVICE_ID_VCS = 8 -BTP_SERVICE_ID_IAS = 9 -BTP_SERVICE_ID_AICS = 10 -BTP_SERVICE_ID_VOCS = 11 -BTP_SERVICE_ID_PACS = 12 -BTP_SERVICE_ID_ASCS = 13 -BTP_SERVICE_ID_BAP = 14 -BTP_SERVICE_ID_HAS = 15 -BTP_SERVICE_ID_MICP = 16 -BTP_SERVICE_ID_CSIS = 17 -BTP_SERVICE_ID_MICS = 18 -BTP_SERVICE_ID_CCP = 19 -BTP_SERVICE_ID_VCP = 20 -BTP_SERVICE_ID_CAS = 21 -BTP_SERVICE_ID_MCP = 22 -BTP_SERVICE_ID_GMCS = 23 -BTP_SERVICE_ID_HAP = 24 -BTP_SERVICE_ID_CSIP = 25 -BTP_SERVICE_ID_CAP = 26 -BTP_SERVICE_ID_TBS = 27 -BTP_SERVICE_ID_TMAP = 28 -BTP_SERVICE_ID_OTS = 29 -BTP_SERVICE_ID_PBP = 30 +BTP_SERVICE_ID_CORE = 0x00 +BTP_SERVICE_ID_GAP = 0x01 +BTP_SERVICE_ID_GATT = 0x02 +BTP_SERVICE_ID_L2CAP = 0x03 +BTP_SERVICE_ID_MESH = 0x04 +BTP_SERVICE_ID_MMDL = 0x05 +BTP_SERVICE_ID_GATTC = 0x06 +BTP_SERVICE_ID_VCS = 0x08 +BTP_SERVICE_ID_IAS = 0x09 +BTP_SERVICE_ID_AICS = 0x0a +BTP_SERVICE_ID_VOCS = 0x0b +BTP_SERVICE_ID_PACS = 0x0c +BTP_SERVICE_ID_ASCS = 0x0d +BTP_SERVICE_ID_BAP = 0x0e +BTP_SERVICE_ID_HAS = 0x0f +BTP_SERVICE_ID_MICP = 0x10 +BTP_SERVICE_ID_CSIS = 0x11 +BTP_SERVICE_ID_MICS = 0x12 +BTP_SERVICE_ID_CCP = 0x13 +BTP_SERVICE_ID_VCP = 0x14 +BTP_SERVICE_ID_CAS = 0x15 +BTP_SERVICE_ID_MCP = 0x16 +BTP_SERVICE_ID_GMCS = 0x17 +BTP_SERVICE_ID_HAP = 0x18 +BTP_SERVICE_ID_CSIP = 0x19 +BTP_SERVICE_ID_CAP = 0x1a +BTP_SERVICE_ID_TBS = 0x1b +BTP_SERVICE_ID_TMAP = 0x1c +BTP_SERVICE_ID_OTS = 0x1d +BTP_SERVICE_ID_PBP = 0x1f # GENERATOR append 1 BTP_STATUS_SUCCESS = 0x00 From 057e5afa064f90df13201ef3abd566172bf82b9b Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Tue, 5 Nov 2024 14:13:59 +0100 Subject: [PATCH 19/32] Log BTP headers as hex Log BTP headers as hex instead of decimal so it is easier to compare to the defined values in defs.py Since the headers are using a namedtuple instead of a class, it is not straigh forward to just update the str or repr functions of the class. Since printing a namedtuple uses the repr of the class, a new function, repr_hdr, was added to format the header as a string as hex. Signed-off-by: Emil Gydesen --- autopts/pybtp/iutctl_common.py | 4 ++-- autopts/pybtp/parser.py | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/autopts/pybtp/iutctl_common.py b/autopts/pybtp/iutctl_common.py index 7d42939d20..d222af1869 100644 --- a/autopts/pybtp/iutctl_common.py +++ b/autopts/pybtp/iutctl_common.py @@ -26,7 +26,7 @@ from autopts.pybtp import defs from autopts.pybtp.types import BTPError -from autopts.pybtp.parser import enc_frame, dec_hdr, dec_data, HDR_LEN +from autopts.pybtp.parser import enc_frame, dec_hdr, repr_hdr, dec_data, HDR_LEN from autopts.utils import get_global_end, raise_on_global_end log = logging.debug @@ -80,7 +80,7 @@ def read(self, timeout=20.0): tuple_hdr = dec_hdr(hdr) toread_data_len = tuple_hdr.data_len - logging.debug("Received: hdr: %r %r", tuple_hdr, hdr) + logging.debug("Received: hdr: %s %r", repr_hdr(tuple_hdr), hdr) data = bytearray(toread_data_len) data_memview = memoryview(data) diff --git a/autopts/pybtp/parser.py b/autopts/pybtp/parser.py index cb34aa8848..8288b308be 100644 --- a/autopts/pybtp/parser.py +++ b/autopts/pybtp/parser.py @@ -34,6 +34,9 @@ def dec_hdr(frame): return Header._make(struct.unpack(" Date: Tue, 5 Nov 2024 17:24:50 +0100 Subject: [PATCH 20/32] bot/zephyr: Use EXTRA_CONF_FILE instead of OVERLAY_CONFIG OVERLAY_CONFIG was deprected in Zephyr 3.4: https://docs.zephyrproject.org/latest/releases/release-notes-3.4.html#build-system-and-infrastructure --- autopts/bot/zephyr.py | 2 +- autopts/ptsprojects/boards/nrf52_wsl.py | 2 +- autopts/ptsprojects/boards/nrf53.py | 4 ++-- autopts/ptsprojects/boards/nrf53_appcore.py | 2 +- autopts/ptsprojects/boards/nrf53_audio.py | 6 +++--- autopts/ptsprojects/boards/nrf54h.py | 2 +- autopts/ptsprojects/boards/nrf5x.py | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/autopts/bot/zephyr.py b/autopts/bot/zephyr.py index 75e9435c6f..1f0c6c8c63 100755 --- a/autopts/bot/zephyr.py +++ b/autopts/bot/zephyr.py @@ -125,7 +125,7 @@ def apply_config(self, args, config, value): configs.append(name) - # The order is used in the -DOVERLAY_CONFIG=";<...>" option. + # The order is used in the -DEXTRA_CONF_FILE=";<...>" option. overlays = ';'.join(configs) log("TTY path: %s" % args.tty_file) diff --git a/autopts/ptsprojects/boards/nrf52_wsl.py b/autopts/ptsprojects/boards/nrf52_wsl.py index a4dc859633..29007ccb9d 100644 --- a/autopts/ptsprojects/boards/nrf52_wsl.py +++ b/autopts/ptsprojects/boards/nrf52_wsl.py @@ -49,7 +49,7 @@ def build_and_flash(zephyr_wd, board, debugger_snr, conf_file=None, *args): cmd = ['west', 'build', '-p', 'auto', '-b', board] if conf_file and conf_file != 'default' and conf_file != 'prj.conf': - cmd.extend(('--', '-DOVERLAY_CONFIG=\'{}\''.format(conf_file))) + cmd.extend(('--', '-DEXTRA_CONF_FILE=\'{}\''.format(conf_file))) shell = True if sys.platform == 'win32': diff --git a/autopts/ptsprojects/boards/nrf53.py b/autopts/ptsprojects/boards/nrf53.py index aa62a50c3a..38d0c1ba8b 100644 --- a/autopts/ptsprojects/boards/nrf53.py +++ b/autopts/ptsprojects/boards/nrf53.py @@ -40,12 +40,12 @@ def build_and_flash(zephyr_wd, board, debugger_snr, conf_file=None, *args): if conf_file and conf_file != 'default' and conf_file != 'prj.conf': bttester_overlay += f';{conf_file}' - cmd = ['west', 'build', '-b', board, '--', f'-DOVERLAY_CONFIG=\'{bttester_overlay}\''] + cmd = ['west', 'build', '-b', board, '--', f'-DEXTRA_CONF_FILE=\'{bttester_overlay}\''] check_call(cmd, cwd=tester_dir) check_call(['west', 'flash', '--skip-rebuild', '--recover', '-i', debugger_snr], cwd=tester_dir) cmd = ['west', 'build', '-b', 'nrf5340dk/nrf5340/cpunet', '--', - f'-DOVERLAY_CONFIG=\'nrf5340_cpunet_iso-bt_ll_sw_split.conf;' + f'-DEXTRA_CONF_FILE=\'nrf5340_cpunet_iso-bt_ll_sw_split.conf;' f'../../../tests/bluetooth/tester/nrf5340_hci_ipc_cpunet.conf\''] check_call(cmd, cwd=controller_dir) check_call(['west', 'flash', '--skip-rebuild', '-i', debugger_snr], cwd=controller_dir) diff --git a/autopts/ptsprojects/boards/nrf53_appcore.py b/autopts/ptsprojects/boards/nrf53_appcore.py index d9d03e6759..e0678617c6 100644 --- a/autopts/ptsprojects/boards/nrf53_appcore.py +++ b/autopts/ptsprojects/boards/nrf53_appcore.py @@ -38,6 +38,6 @@ def build_and_flash(zephyr_wd, board, debugger_snr, conf_file=None, *args): if conf_file and conf_file != 'default' and conf_file != 'prj.conf': bttester_overlay += f';{conf_file}' - cmd = ['west', 'build', '-b', board, '--', f'-DOVERLAY_CONFIG=\'{bttester_overlay}\''] + cmd = ['west', 'build', '-b', board, '--', f'-DEXTRA_CONF_FILE=\'{bttester_overlay}\''] check_call(cmd, cwd=tester_dir) check_call(['west', 'flash', '--skip-rebuild', '--recover', '-i', debugger_snr], cwd=tester_dir) diff --git a/autopts/ptsprojects/boards/nrf53_audio.py b/autopts/ptsprojects/boards/nrf53_audio.py index 51dd8e649f..da70f67467 100644 --- a/autopts/ptsprojects/boards/nrf53_audio.py +++ b/autopts/ptsprojects/boards/nrf53_audio.py @@ -57,7 +57,7 @@ def build_and_flash(zephyr_wd, board, debugger_snr, conf_file=None, *args): app_core_configs = [] if conf_file and conf_file != 'default' and conf_file != 'prj.conf': - app_core_configs = [f'OVERLAY_CONFIG=\'{conf_file}\''] + app_core_configs = [f'EXTRA_CONF_FILE=\'{conf_file}\''] build_and_flash_core(zephyr_wd, source_dir, @@ -68,11 +68,11 @@ def build_and_flash(zephyr_wd, board, debugger_snr, conf_file=None, *args): config_dir_net = os.getenv("AUTOPTS_SOURCE_DIR_NET") if config_dir_net is None: - net_core_configs = [f'OVERLAY_CONFIG=\'nrf5340_cpunet_iso-bt_ll_sw_split.conf;' + net_core_configs = [f'EXTRA_CONF_FILE=\'nrf5340_cpunet_iso-bt_ll_sw_split.conf;' f'../../../tests/bluetooth/tester/nrf5340_hci_ipc_cpunet.conf\''] else: conf_path = os.path.join(zephyr_wd, config_dir_net, 'hci_ipc.conf') - net_core_configs = [f'OVERLAY_CONFIG=\'{conf_path}\''] + net_core_configs = [f'EXTRA_CONF_FILE=\'{conf_path}\''] build_and_flash_core(zephyr_wd, os.path.join('samples', 'bluetooth', 'hci_ipc'), diff --git a/autopts/ptsprojects/boards/nrf54h.py b/autopts/ptsprojects/boards/nrf54h.py index 6910a3b5e6..bafcda1cb1 100644 --- a/autopts/ptsprojects/boards/nrf54h.py +++ b/autopts/ptsprojects/boards/nrf54h.py @@ -48,7 +48,7 @@ def build_and_flash(zephyr_wd, board, debugger_snr, conf_file=None, *args): if conf_file and conf_file not in ['default', 'prj.conf']: if 'audio' in conf_file: conf_file += ';overlay-le-audio-ctlr.conf' - cmd.extend(('--', f'-DOVERLAY_CONFIG=\'{conf_file}\'')) + cmd.extend(('--', f'-DEXTRA_CONF_FILE=\'{conf_file}\'')) check_call(cmd, cwd=tester_dir) check_call(['west', 'flash', '--skip-rebuild', diff --git a/autopts/ptsprojects/boards/nrf5x.py b/autopts/ptsprojects/boards/nrf5x.py index 9d211bec51..f607edf1e9 100644 --- a/autopts/ptsprojects/boards/nrf5x.py +++ b/autopts/ptsprojects/boards/nrf5x.py @@ -48,7 +48,7 @@ def build_and_flash(zephyr_wd, board, debugger_snr, conf_file=None, *args): if conf_file and conf_file not in ['default', 'prj.conf']: if 'audio' in conf_file: conf_file += ';overlay-le-audio-ctlr.conf' - cmd.extend(('--', f'-DOVERLAY_CONFIG=\'{conf_file}\'')) + cmd.extend(('--', f'-DEXTRA_CONF_FILE=\'{conf_file}\'')) check_call(cmd, cwd=tester_dir) check_call(['west', 'flash', '--skip-rebuild', '--recover', From fef6299cc235ba5825ed618538f6c25c7c0246fc Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 6 Nov 2024 11:22:19 +0100 Subject: [PATCH 21/32] cap: Register TBS to have 2 CCIDs registered The following tests require 2 CCIDs, and are failing if the device does not have have 2 CCIDs registered: CAP/INI/BST/BV-07-C CAP/INI/BST/BV-10-C CAP/INI/UST/BV-13-C CAP/INI/UST/BV-14-C CAP/INI/UST/BV-27-C CAP/INI/UST/BV-28-C CAP/INI/UST/BV-31-C CAP/INI/UST/BV-36-C CAP/INI/UST/BV-37-C CAP/INI/UTB/BV-04-C Signed-off-by: Emil Gydesen --- autopts/ptsprojects/zephyr/cap.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/autopts/ptsprojects/zephyr/cap.py b/autopts/ptsprojects/zephyr/cap.py index 38b33d0448..290e21fbbc 100644 --- a/autopts/ptsprojects/zephyr/cap.py +++ b/autopts/ptsprojects/zephyr/cap.py @@ -145,8 +145,9 @@ def set_addr(addr): TestFunc(stack.aics_init), TestFunc(btp.core_reg_svc_vocs), TestFunc(stack.vocs_init), - # Enable GMCS to have a second CCID in Zephyr stack + # Enable GMCS and TBS to have 2 CCIDs in Zephyr stack which is required by some tests TestFunc(btp.core_reg_svc_gmcs), + TestFunc(btp.core_reg_svc_tbs), TestFunc(stack.gmcs_init), # Enable CSIP to have access to Start Ordered Access # procedure BTP command From ef21e64a158ae90b73bad5fc04f9177e2a34ae01 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 5 Nov 2024 16:52:33 +0100 Subject: [PATCH 22/32] doc: Define service IDs as hex Make this consistent with rest of opcodes. --- doc/overview.txt | 62 ++++++++++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/doc/overview.txt b/doc/overview.txt index 1f39842870..2d9b0ee833 100644 --- a/doc/overview.txt +++ b/doc/overview.txt @@ -84,35 +84,35 @@ btp_SERVICE_NAME.txt. The currently defined services are listed below. Core Serv is mandatory to be supported by IUT. ID Name - 0 Core Service - 1 GAP Service - 2 GATT Service (DEPRECATED) - 3 L2CAP Service - 4 Mesh Node Service - 5 Mesh Model Service - 6 GATT Client Service - 7 GATT Server Service - 8 VCS Service - 9 IAS Service - 10 AICS Service - 11 VOCS Service - 12 PACS Service - 13 ASCS Service - 14 BAP Service - 15 HAS Service - 16 MICP Service - 17 CSIS Service - 18 MICS Service - 19 CCP Service - 20 VCP Service - 21 CAS Service - 22 MCP Service - 23 GMCS Service - 24 HAP Service - 25 CSIP Service - 26 CAP Service - 27 TBS Service - 28 TMAP Service - 29 OTS Service - 30 PBP Service + 0x00 Core Service + 0x01 GAP Service + 0x02 GATT Service (DEPRECATED) + 0x03 L2CAP Service + 0x04 Mesh Node Service + 0x05 Mesh Model Service + 0x06 GATT Client Service + 0x07 GATT Server Service + 0x08 VCS Service + 0x09 IAS Service + 0x0a AICS Service + 0x0b VOCS Service + 0x0c PACS Service + 0x0d ASCS Service + 0x0e BAP Service + 0x0f HAS Service + 0x10 MICP Service + 0x11 CSIS Service + 0x12 MICS Service + 0x13 CCP Service + 0x14 VCP Service + 0x15 CAS Service + 0x16 MCP Service + 0x17 GMCS Service + 0x18 HAP Service + 0x19 CSIP Service + 0x1a CAP Service + 0x1b TBS Service + 0x1c TMAP Service + 0x1d OTS Service + 0x1e PBP Service # GENERATOR append 1 From 6499091fad8909d3ab0f076a4a3b64f5df6f7c7b Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 5 Nov 2024 16:53:19 +0100 Subject: [PATCH 23/32] pybtp: Fix BTP_SERVICE_ID_PBP value 30 decimal is 0x1e hex. --- autopts/pybtp/defs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autopts/pybtp/defs.py b/autopts/pybtp/defs.py index 23e07b761b..536075cbd6 100644 --- a/autopts/pybtp/defs.py +++ b/autopts/pybtp/defs.py @@ -52,7 +52,7 @@ def BIT(bit): BTP_SERVICE_ID_TBS = 0x1b BTP_SERVICE_ID_TMAP = 0x1c BTP_SERVICE_ID_OTS = 0x1d -BTP_SERVICE_ID_PBP = 0x1f +BTP_SERVICE_ID_PBP = 0x1e # GENERATOR append 1 BTP_STATUS_SUCCESS = 0x00 From 73837ddd4604e7b912671794614d16f24aa19f98 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 4 Nov 2024 22:30:57 +0100 Subject: [PATCH 24/32] errata: Add Request ID 147314 for CSIP and more The Request ID 147314 applies to nearly all tests that uses multiple lower testers, as it affects how IRKs are handled by PTS. Signed-off-by: Emil Gydesen --- errata/common.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/errata/common.yaml b/errata/common.yaml index 934e90f05c..782ad59d66 100644 --- a/errata/common.yaml +++ b/errata/common.yaml @@ -11,3 +11,9 @@ GAP/GAT/BV-17-C: ES-26322 L2CAP/ECFC/BI-02-C: ES-26416 L2CAP/ECFC/BI-11-C: ES-26416 + +# This errata affect so many cases (any test, including non-CSIP) that uses multiple connected lower testers, but we only track it for CSIP where it's most common +CSIP/CL/SP/BV-03-C: Request ID 147314 +CSIP/CL/SP/BV-04-C: Request ID 147314 +CSIP/CL/SP/BV-07-C: Request ID 147314 +CSIP/CL/SPE/BI-01-C: Request ID 147314 From 1ebfe16e6633dd5924d2a3fc945b18add78abd80 Mon Sep 17 00:00:00 2001 From: Magdalena Kasenberg Date: Thu, 10 Oct 2024 21:31:22 +0200 Subject: [PATCH 25/32] server: Add workaround for PTS issue 145370 If a PTS dongle has been corrupted, its stack has to be reinitialized. The PTS apparently can do this by calling GetPTSBluetoothAddress() before RunTestCase(). The dongle verification takes less than 100ms on a real-hardware machine, but for VM it might take longer. Let's add an option --dongle_init_delay that allows to customize this time. --- autopts/ptscontrol.py | 20 ++++++++++++++++++++ autoptsserver.py | 7 +++++++ 2 files changed, 27 insertions(+) diff --git a/autopts/ptscontrol.py b/autopts/ptscontrol.py index 1ec828f9f3..c18707674d 100644 --- a/autopts/ptscontrol.py +++ b/autopts/ptscontrol.py @@ -784,6 +784,26 @@ def run_test_case(self, project_name, test_case_name): self._pts_logger.set_test_case_name(test_case_name) self._pts_sender.reopen() + # Workaround for PTS issue 145370. + # PTS server can detect that the PTS dongle had been corrupted + # by calling GetPTSBluetoothAddress() before test case started. + address = None + for i in range(10): + try: + address = self._pts.GetPTSBluetoothAddress() + log(f"GetPTSBluetoothAddress(): {address}") + if address: + break + except Exception as e: + log(e) + finally: + # The dongle verification should take less than 100ms, + # but it might take longer on a slow VM. + time.sleep(float(os.environ.get('GLOBAL_DONGLE_INIT_DELAY'))) + + if not address: + raise Exception("Bluetooth address not available") + self._pts.RunTestCase(project_name, test_case_name) err = self._pts_logger.get_test_case_status(timeout=30) diff --git a/autoptsserver.py b/autoptsserver.py index 735a1b4920..1104d9676f 100755 --- a/autoptsserver.py +++ b/autoptsserver.py @@ -325,6 +325,11 @@ def __init__(self, description): r'"Device instance path" in device settings, e.g. ' r'"USB\VID_0A12&PID_0001\5&A70BC4C&0&8"') + self.add_argument("--dongle_init_delay", default=0.1, type=float, metavar='SECONDS', + help="Specify amount of time in seconds to wait before RunTestCase()" + "after dongle reinitialization has been triggered with" + "GetPTSBluetoothAddress().") + @staticmethod def check_args(arg): """Sanity check command line arguments""" @@ -370,6 +375,8 @@ def check_args(arg): arg.active_hub_server = active_hub_server_configs arg.active_hub = True + os.environ['GLOBAL_DONGLE_INIT_DELAY'] = str(arg.dongle_init_delay) + def parse_args(self, args=None, namespace=None): namespace = argparse.Namespace(active_hub=None) arg = super().parse_args(args, namespace) From 06d7c0065309b20317c36a8e3e776b42fa2595d7 Mon Sep 17 00:00:00 2001 From: Magdalena Kasenberg Date: Mon, 28 Oct 2024 14:58:47 +0100 Subject: [PATCH 26/32] cron: Add retry to _restart_processes It happens rarely, but sometimes a socket port does not get released in time and is not usable for a while. File "/home/codecoup/workspace/autopts/auto-pts-cron/tools/cron/common.py", line 653, in run_test _run_test(config) File "/home/codecoup/workspace/autopts/auto-pts-cron/tools/cron/common.py", line 644, in _run_test srv_process, bot_process = _restart_processes(config) File "/home/codecoup/workspace/autopts/auto-pts-cron/tools/cron/common.py", line 582, in _restart_processes return _start_processes(config, checkout_repos=False) File "/home/codecoup/workspace/autopts/auto-pts-cron/tools/cron/common.py", line 557, in _start_processes start_remote_autoptsserver(config, checkout_repos) File "/home/codecoup/workspace/autopts/auto-pts-cron/tools/cron/common.py", line 474, in start_remote_autoptsserver log(client.open_process(config['server_start_cmd'], File "/usr/lib/python3.10/xmlrpc/client.py", line 1122, in __call__ return self.__send(self.__name, args) self.sock = self._create_connection( (...) File "/usr/lib/python3.10/socket.py", line 833, in create_connection sock.connect(sa) OSError: [Errno 113] No route to host --- tools/cron/common.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/cron/common.py b/tools/cron/common.py index 3d12d78ee3..f5b57bc08a 100644 --- a/tools/cron/common.py +++ b/tools/cron/common.py @@ -578,8 +578,12 @@ def _start_processes(config, checkout_repos): def _restart_processes(config): - terminate_processes(config) - return _start_processes(config, checkout_repos=False) + while not config['cron']['cancel_job'].canceled: + try: + terminate_processes(config) + return _start_processes(config, checkout_repos=False) + except OSError: + log(traceback.format_exc()) def _run_test(config): From 65092c6f257e6cba1c3996355dd8b62193fa6aa6 Mon Sep 17 00:00:00 2001 From: Piotr Narajowski Date: Thu, 14 Nov 2024 12:44:54 +0100 Subject: [PATCH 27/32] client: adjust exception logging When running autoptsclient-zephyr.py --help, traceback was printed in terminal. This was caused by logging.exception(e) which should not be called when exiting with status 0. --- autopts/client.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/autopts/client.py b/autopts/client.py index 4f537b9754..e85965bdae 100755 --- a/autopts/client.py +++ b/autopts/client.py @@ -1361,9 +1361,12 @@ def sigint_handler(sig, frame): signal.signal(signal.SIGINT, sigint_handler) return self.main(args) - except BaseException as e: # Ctrl-C - if not isinstance(e, KeyboardInterrupt): - logging.exception(e) + except BaseException as e: + if not isinstance(e, KeyboardInterrupt): # Ctrl-C + if e.code != 0: + # Exit with traceback + logging.exception(e) + set_global_end() self.cleanup() raise From 9ff06175ff5db92ce197789faea9eb4081c08fb3 Mon Sep 17 00:00:00 2001 From: Piotr Narajowski Date: Thu, 14 Nov 2024 15:46:42 +0100 Subject: [PATCH 28/32] client: ignore retry param for MISSING WID ERROR There is no point in repeating test case if MISSING WID ERROR is returned. --- autopts/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autopts/client.py b/autopts/client.py index e85965bdae..66859c3523 100755 --- a/autopts/client.py +++ b/autopts/client.py @@ -1280,7 +1280,7 @@ def run_test_cases(ptses, test_case_instances, args, stats, **kwargs): if repeat_until_failed and status == 'PASS': continue - if (status == 'PASS' and not args.stress_test) or \ + if (status in ('PASS', 'MISSING WID ERROR') and not args.stress_test) or \ stats.run_count == retry_limit: if stats.db: stats.db.update_statistics(test_case, duration, status) From ca4acba344e3a19ab46271651895a2f2ec4e08c3 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Fri, 8 Nov 2024 17:00:15 +0100 Subject: [PATCH 29/32] errata: Add list of CAP tests failing when PTS dongle crashes These tests (and possibly more) makes the PTS dongle crash. Tested with both SDC and ZLL with the Zephyr host, using sha 67980643d799f76aff93118346a8dabfb472a642. Signed-off-by: Emil Gydesen --- errata/common.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/errata/common.yaml b/errata/common.yaml index 782ad59d66..2a407f6a94 100644 --- a/errata/common.yaml +++ b/errata/common.yaml @@ -17,3 +17,9 @@ CSIP/CL/SP/BV-03-C: Request ID 147314 CSIP/CL/SP/BV-04-C: Request ID 147314 CSIP/CL/SP/BV-07-C: Request ID 147314 CSIP/CL/SPE/BI-01-C: Request ID 147314 + +CAP/INI/BST/BV-01-C: Request ID 147512 +CAP/INI/BST/BV-03-C: Request ID 147512 +CAP/INI/BST/BV-05-C: Request ID 147512 +CAP/INI/BST/BV-08-C: Request ID 147512 +CAP/INI/BST/BV-16-C: Request ID 147512 From 0879a4e09c26ebc3e9d0598a611335f186c31697 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 10 Oct 2024 21:00:43 +0200 Subject: [PATCH 30/32] zephyr: Fix cap.hdl_wid_312 to use cap unicast stop Modified the hdl_wid_312 handler to call cap_unicast_audio_stop with release = False, so that it performs a disable (and stop) without release. Why PTS wants us to disable first is unclear, as the test spec states to release, which would be handled by hdl_wid_309. This affects tests where PTS asks us to stop/disable the streams (hdl_wid_312) before releasing it (hdl_wid_309), such as CAP/INI/UST/BV-40-C. Signed-off-by: Emil Gydesen --- autopts/pybtp/btp/cap.py | 10 +++++++++- autopts/wid/cap.py | 38 +++++++++----------------------------- doc/btp_cap.txt | 4 ++++ 3 files changed, 22 insertions(+), 30 deletions(-) diff --git a/autopts/pybtp/btp/cap.py b/autopts/pybtp/btp/cap.py index 20e9afaa3e..5c876337ce 100644 --- a/autopts/pybtp/btp/cap.py +++ b/autopts/pybtp/btp/cap.py @@ -122,11 +122,19 @@ def cap_unicast_audio_update(metadata_tuple): cap_command_rsp_succ() -def cap_unicast_audio_stop(cig_id): +BTP_CAP_UNICAST_AUDIO_STOP_FLAG_RELEASE = 0b00000001 + +def cap_unicast_audio_stop(cig_id, release): logging.debug(f"{cap_unicast_audio_stop.__name__}") data = struct.pack('B', cig_id) + flags = 0x00 + if release: + flags |= BTP_CAP_UNICAST_AUDIO_STOP_FLAG_RELEASE + + data += struct.pack('?', flags) + iutctl = get_iut() iutctl.btp_socket.send(*CAP['unicast_audio_stop'], data=data) diff --git a/autopts/wid/cap.py b/autopts/wid/cap.py index 0e5c35ded9..efa92a07d6 100644 --- a/autopts/wid/cap.py +++ b/autopts/wid/cap.py @@ -213,11 +213,12 @@ def hdl_wid_202(_: WIDParams): def hdl_wid_309(params: WIDParams): + """ Please configure ASE state to Releasing state. """ if params.test_case_name.endswith('LT2'): return True cig_id = 0x00 - btp.cap_unicast_audio_stop(cig_id) + btp.cap_unicast_audio_stop(cig_id, True) stack = get_stack() ev = stack.cap.wait_unicast_stop_completed_ev(cig_id, 20) @@ -248,37 +249,16 @@ def hdl_wid_310(params: WIDParams): def hdl_wid_312(params: WIDParams): """Please configure ASE state to Disable""" if params.test_case_name.endswith('LT2'): - addr = lt2_addr_get() - addr_type = lt2_addr_type_get() - else: - addr = pts_addr_get() - addr_type = pts_addr_type_get() + return True - configs = [] - stack = get_stack() - for ase in stack.bap.ase_configs: - if ase.addr == addr: - configs.append(ase) + cig_id = 0x00 + btp.cap_unicast_audio_stop(cig_id, False) - if not configs: - log('No ASE ID found in configs') + stack = get_stack() + ev = stack.cap.wait_unicast_stop_completed_ev(cig_id, 20) + if ev is None: return False - stack.ascs.event_queues[defs.ASCS_EV_OPERATION_COMPLETED].clear() - for config in configs: - btp.ascs_disable(config.ase_id, addr_type, addr) - ev = stack.ascs.wait_ascs_operation_complete_ev(addr_type, addr, config.ase_id, 10) - if ev is None: - raise Exception("Disable command failed") - - for config in configs: - if config.audio_dir == AudioDir.SOURCE: - # Initiate receiver Stop Ready - btp.ascs_receiver_stop_ready(config.ase_id, addr_type, addr) - ev = stack.ascs.wait_ascs_operation_complete_ev(addr_type, addr, config.ase_id, 10) - if ev is None: - raise Exception("Receiver Stop Ready command failed") - return True @@ -803,7 +783,7 @@ def hdl_wid_406(params: WIDParams): return True cig_id = 0x00 - btp.cap_unicast_audio_stop(cig_id) + btp.cap_unicast_audio_stop(cig_id, True) stack = get_stack() ev = stack.cap.wait_unicast_stop_completed_ev(cig_id, 20) diff --git a/doc/btp_cap.txt b/doc/btp_cap.txt index b5478553f0..9e18710079 100644 --- a/doc/btp_cap.txt +++ b/doc/btp_cap.txt @@ -102,6 +102,10 @@ Commands and responses: Opcode 0x06 - Unicast Audio Stop Controller Index: Command parameters: CIG_ID (1 octet) + Command parameters: Flags (1 octet) + where: + - Flags is a bit map of settings: + bit 0: To release the streams. If not set, the streams will only be disabled. Response parameters: From 8c0e82ac46cda5cb1ae8ea743be6b09f4d3959d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ayt=C3=BCrk=20D=C3=BCzen?= Date: Thu, 21 Nov 2024 11:53:58 +0100 Subject: [PATCH 31/32] zephyr: boards: adapt 53/54h for sysbuild configs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add sysbuild option for 54h20 Pass --no-sysbuild for 5340 same as old behaviour Signed-off-by: Aytürk Düzen --- autopts/ptsprojects/boards/nrf53.py | 4 ++-- autopts/ptsprojects/boards/nrf53_appcore.py | 2 +- autopts/ptsprojects/boards/nrf53_audio.py | 2 +- autopts/ptsprojects/boards/nrf54h.py | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/autopts/ptsprojects/boards/nrf53.py b/autopts/ptsprojects/boards/nrf53.py index 38d0c1ba8b..c5c14ee2d5 100644 --- a/autopts/ptsprojects/boards/nrf53.py +++ b/autopts/ptsprojects/boards/nrf53.py @@ -40,11 +40,11 @@ def build_and_flash(zephyr_wd, board, debugger_snr, conf_file=None, *args): if conf_file and conf_file != 'default' and conf_file != 'prj.conf': bttester_overlay += f';{conf_file}' - cmd = ['west', 'build', '-b', board, '--', f'-DEXTRA_CONF_FILE=\'{bttester_overlay}\''] + cmd = ['west', 'build', '--no-sysbuild', '-b', board, '--', f'-DEXTRA_CONF_FILE=\'{bttester_overlay}\''] check_call(cmd, cwd=tester_dir) check_call(['west', 'flash', '--skip-rebuild', '--recover', '-i', debugger_snr], cwd=tester_dir) - cmd = ['west', 'build', '-b', 'nrf5340dk/nrf5340/cpunet', '--', + cmd = ['west', 'build', '--no-sysbuild', '-b', 'nrf5340dk/nrf5340/cpunet', '--', f'-DEXTRA_CONF_FILE=\'nrf5340_cpunet_iso-bt_ll_sw_split.conf;' f'../../../tests/bluetooth/tester/nrf5340_hci_ipc_cpunet.conf\''] check_call(cmd, cwd=controller_dir) diff --git a/autopts/ptsprojects/boards/nrf53_appcore.py b/autopts/ptsprojects/boards/nrf53_appcore.py index e0678617c6..e4282d7dfb 100644 --- a/autopts/ptsprojects/boards/nrf53_appcore.py +++ b/autopts/ptsprojects/boards/nrf53_appcore.py @@ -38,6 +38,6 @@ def build_and_flash(zephyr_wd, board, debugger_snr, conf_file=None, *args): if conf_file and conf_file != 'default' and conf_file != 'prj.conf': bttester_overlay += f';{conf_file}' - cmd = ['west', 'build', '-b', board, '--', f'-DEXTRA_CONF_FILE=\'{bttester_overlay}\''] + cmd = ['west', 'build', '--no-sysbuild', '-b', board, '--', f'-DEXTRA_CONF_FILE=\'{bttester_overlay}\''] check_call(cmd, cwd=tester_dir) check_call(['west', 'flash', '--skip-rebuild', '--recover', '-i', debugger_snr], cwd=tester_dir) diff --git a/autopts/ptsprojects/boards/nrf53_audio.py b/autopts/ptsprojects/boards/nrf53_audio.py index da70f67467..989df2a6da 100644 --- a/autopts/ptsprojects/boards/nrf53_audio.py +++ b/autopts/ptsprojects/boards/nrf53_audio.py @@ -28,7 +28,7 @@ def build_and_flash_core(zephyr_wd, build_dir, board, debugger_snr, configs, rec overlay = '-- -DCMAKE_C_FLAGS="-Werror"' for conf in configs: overlay += f' -D{conf}' - cmd = ['west', 'build', '-b', board] + cmd = ['west', 'build', '--no-sysbuild', '-b', board] cmd.extend(overlay.split()) check_call(cmd, cwd=build_dir) diff --git a/autopts/ptsprojects/boards/nrf54h.py b/autopts/ptsprojects/boards/nrf54h.py index bafcda1cb1..cc9acbc398 100644 --- a/autopts/ptsprojects/boards/nrf54h.py +++ b/autopts/ptsprojects/boards/nrf54h.py @@ -44,7 +44,7 @@ def build_and_flash(zephyr_wd, board, debugger_snr, conf_file=None, *args): check_call('rm -rf build/'.split(), cwd=tester_dir) - cmd = ['west', 'build', '-p', 'auto', '-b', board] + cmd = ['west', 'build', '--sysbuild', '-p', 'auto', '-b', board] if conf_file and conf_file not in ['default', 'prj.conf']: if 'audio' in conf_file: conf_file += ';overlay-le-audio-ctlr.conf' From f6b7006d9d57df388a91447618b74b44dd401e1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ayt=C3=BCrk=20D=C3=BCzen?= Date: Fri, 22 Nov 2024 10:58:19 +0100 Subject: [PATCH 32/32] zephyr: boards: make 5340_hci_ipc_* generic config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit rename hci_ipc configuration for generic multicore usage. related change in tester: https://github.com/zephyrproject-rtos/zephyr/pull/81755 Signed-off-by: Aytürk Düzen --- autopts/ptsprojects/boards/nrf53.py | 4 ++-- autopts/ptsprojects/boards/nrf53_appcore.py | 2 +- autopts/ptsprojects/boards/nrf53_audio.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/autopts/ptsprojects/boards/nrf53.py b/autopts/ptsprojects/boards/nrf53.py index c5c14ee2d5..a200111260 100644 --- a/autopts/ptsprojects/boards/nrf53.py +++ b/autopts/ptsprojects/boards/nrf53.py @@ -35,7 +35,7 @@ def build_and_flash(zephyr_wd, board, debugger_snr, conf_file=None, *args): check_call('rm -rf build/'.split(), cwd=tester_dir) check_call('rm -rf build/'.split(), cwd=controller_dir) - bttester_overlay = 'nrf5340_hci_ipc.conf' + bttester_overlay = 'hci_ipc.conf' if conf_file and conf_file != 'default' and conf_file != 'prj.conf': bttester_overlay += f';{conf_file}' @@ -46,6 +46,6 @@ def build_and_flash(zephyr_wd, board, debugger_snr, conf_file=None, *args): cmd = ['west', 'build', '--no-sysbuild', '-b', 'nrf5340dk/nrf5340/cpunet', '--', f'-DEXTRA_CONF_FILE=\'nrf5340_cpunet_iso-bt_ll_sw_split.conf;' - f'../../../tests/bluetooth/tester/nrf5340_hci_ipc_cpunet.conf\''] + f'../../../tests/bluetooth/tester/hci_ipc_cpunet.conf\''] check_call(cmd, cwd=controller_dir) check_call(['west', 'flash', '--skip-rebuild', '-i', debugger_snr], cwd=controller_dir) diff --git a/autopts/ptsprojects/boards/nrf53_appcore.py b/autopts/ptsprojects/boards/nrf53_appcore.py index e4282d7dfb..e26e8fa1da 100644 --- a/autopts/ptsprojects/boards/nrf53_appcore.py +++ b/autopts/ptsprojects/boards/nrf53_appcore.py @@ -33,7 +33,7 @@ def build_and_flash(zephyr_wd, board, debugger_snr, conf_file=None, *args): check_call('rm -rf build/'.split(), cwd=tester_dir) - bttester_overlay = 'nrf5340_hci_ipc.conf' + bttester_overlay = 'hci_ipc.conf' if conf_file and conf_file != 'default' and conf_file != 'prj.conf': bttester_overlay += f';{conf_file}' diff --git a/autopts/ptsprojects/boards/nrf53_audio.py b/autopts/ptsprojects/boards/nrf53_audio.py index 989df2a6da..9e1d0cf194 100644 --- a/autopts/ptsprojects/boards/nrf53_audio.py +++ b/autopts/ptsprojects/boards/nrf53_audio.py @@ -69,7 +69,7 @@ def build_and_flash(zephyr_wd, board, debugger_snr, conf_file=None, *args): config_dir_net = os.getenv("AUTOPTS_SOURCE_DIR_NET") if config_dir_net is None: net_core_configs = [f'EXTRA_CONF_FILE=\'nrf5340_cpunet_iso-bt_ll_sw_split.conf;' - f'../../../tests/bluetooth/tester/nrf5340_hci_ipc_cpunet.conf\''] + f'../../../tests/bluetooth/tester/hci_ipc_cpunet.conf\''] else: conf_path = os.path.join(zephyr_wd, config_dir_net, 'hci_ipc.conf') net_core_configs = [f'EXTRA_CONF_FILE=\'{conf_path}\'']