You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

181 lines
7.4 KiB

#!/usr/bin/env python3
#
# Copyright 2021 - 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.
import logging
from bluetooth_packets_python3 import hci_packets
from cert.capture import Capture
from cert.captures import SecurityCaptures
from cert.closable import Closable
from cert.closable import safeClose
from cert.event_stream import EventStream, IEventStream
from cert.event_stream import FilteringEventStream
from cert.matchers import IsoMatchers
from cert.truth import assertThat
from datetime import timedelta
from facade import common_pb2 as common
from google.protobuf import empty_pb2 as empty_proto
from iso import facade_pb2 as iso_facade_pb2
class CisTestParameters():
def __init__(self, cis_id, nse, max_sdu_m_to_s, max_sdu_s_to_m, max_pdu_m_to_s, max_pdu_s_to_m, phy_m_to_s,
phy_s_to_m, bn_m_to_s, bn_s_to_m):
self.cis_id = cis_id
self.nse = nse
self.max_sdu_m_to_s = max_sdu_m_to_s
self.max_sdu_s_to_m = max_sdu_s_to_m
self.max_pdu_m_to_s = max_pdu_m_to_s
self.max_pdu_s_to_m = max_pdu_s_to_m
self.phy_m_to_s = phy_m_to_s
self.phy_s_to_m = phy_s_to_m
self.bn_m_to_s = bn_m_to_s
self.bn_s_to_m = bn_s_to_m
class PyLeIsoStream(IEventStream):
def __init__(self, device, cis_handle, iso_data_stream):
self._device = device
self._cis_handle = cis_handle
self._le_iso_data_stream = iso_data_stream
self._our_le_iso_cis_view = FilteringEventStream(
self._le_iso_data_stream, IsoMatchers.PacketPayloadWithMatchingCisHandle(self._cis_handle))
def get_event_queue(self):
return self._our_le_iso_cis_view.get_event_queue()
def send(self, payload):
self._device.iso.SendIsoPacket(iso_facade_pb2.IsoPacket(handle=self._cis_handle, payload=payload))
class PyLeIso(Closable):
"""
Abstraction for iso tasks and GRPC calls
"""
_iso_event_stream = None
def __init__(self, device):
logging.info("DUT: Init")
self._device = device
self._device.wait_channel_ready()
self._iso_event_stream = EventStream(self._device.iso.FetchIsoEvents(empty_proto.Empty()))
self._iso_data_stream = EventStream(self._device.iso.FetchIsoData(empty_proto.Empty()))
def close(self):
if self._iso_event_stream is not None:
safeClose(self._iso_event_stream)
else:
logging.info("DUT: ISO Event Stream is None!")
if self._iso_data_stream is not None:
safeClose(self._iso_data_stream)
else:
logging.info("DUT: ISO Data Stream is None!")
logging.info("DUT: close")
def le_set_cig_parameters(self, cig_id, sdu_interval_m_to_s, sdu_interval_s_to_m, peripherals_clock_accuracy,
packing, framing, max_transport_latency_m_to_s, max_transport_latency_s_to_m, cis_id,
max_sdu_m_to_s, max_sdu_s_to_m, phy_m_to_s, phy_s_to_m, rtn_m_to_s, rtn_s_to_m):
resp = self._device.iso.LeSetCigParameters(
iso_facade_pb2.LeSetCigParametersRequest(
cig_id=cig_id,
sdu_interval_m_to_s=sdu_interval_m_to_s,
sdu_interval_s_to_m=sdu_interval_s_to_m,
peripherals_clock_accuracy=peripherals_clock_accuracy,
packing=packing,
framing=framing,
max_transport_latency_m_to_s=max_transport_latency_m_to_s,
max_transport_latency_s_to_m=max_transport_latency_s_to_m,
cis_id=cis_id,
max_sdu_m_to_s=max_sdu_m_to_s,
max_sdu_s_to_m=max_sdu_s_to_m,
phy_m_to_s=phy_m_to_s,
phy_s_to_m=phy_s_to_m,
rtn_m_to_s=rtn_m_to_s,
rtn_s_to_m=rtn_s_to_m))
def le_set_cig_parameters_test(self, cig_id, sdu_interval_m_to_s, sdu_interval_s_to_m, ft_m_to_s, ft_s_to_m,
iso_interval, peripherals_clock_accuracy, packing, framing,
max_transport_latency_m_to_s, max_transport_latency_s_to_m, cis_configs):
configs = []
for cc in cis_configs:
configs.append(
iso_facade_pb2.LeSetCigParametersTestRequest.LeCisParametersTestConfig(
cis_id=cc.cis_id,
nse=cc.nse,
max_sdu_m_to_s=cc.max_sdu_m_to_s,
max_sdu_s_to_m=cc.max_sdu_s_to_m,
max_pdu_m_to_s=cc.max_pdu_m_to_s,
max_pdu_s_to_m=cc.max_pdu_s_to_m,
phy_m_to_s=cc.phy_m_to_s,
phy_s_to_m=cc.phy_s_to_m,
bn_m_to_s=cc.bn_m_to_s,
bn_s_to_m=cc.bn_s_to_m,
))
resp = self._device.iso.LeSetCigParameters(
iso_facade_pb2.LeSetCigParametersTestRequest(
cig_id=cig_id,
sdu_interval_m_to_s=sdu_interval_m_to_s,
sdu_interval_s_to_m=sdu_interval_s_to_m,
ft_m_to_s=ft_m_to_s,
ft_s_to_m=ft_s_to_m,
iso_interval=iso_interval,
peripherals_clock_accuracy=peripherals_clock_accuracy,
packing=packing,
framing=framing,
max_transport_latency_m_to_s=max_transport_latency_m_to_s,
max_transport_latency_s_to_m=max_transport_latency_s_to_m,
cis_configs=configs))
def wait_le_set_cig_parameters_complete(self):
set_cig_params_complete_capture = PyLeIso.IsoCigComplete(iso_facade_pb2.IsoMsgType.ISO_PARAMETERS_SET_COMPLETE)
assertThat(self._iso_event_stream).emits(set_cig_params_complete_capture, timeout=timedelta(seconds=5))
return set_cig_params_complete_capture.get()
@staticmethod
def IsoCigComplete(type=None):
return Capture(lambda event: True if event.message_type == type else False, PyLeIso._extract_cis_handles)
@staticmethod
def _extract_cis_handles(event):
if event is None:
return None
return event.cis_handle
def le_create_cis(self, cis_and_acl_handle_array):
handles_pairs = []
for hp_tmp in cis_and_acl_handle_array:
handles_pairs.append(
iso_facade_pb2.LeCreateCisRequest.HandlePair(cis_handle=hp_tmp[0], acl_handle=hp_tmp[1]))
self._device.iso.LeCreateCis(iso_facade_pb2.LeCreateCisRequest(handle_pair=handles_pairs))
def wait_le_cis_established(self):
cis_establshed_capture = PyLeIso.IsoCigEstablished(iso_facade_pb2.IsoMsgType.ISO_CIS_ESTABLISHED)
assertThat(self._iso_event_stream).emits(cis_establshed_capture, timeout=timedelta(seconds=5))
cis_handle = cis_establshed_capture.get()[0]
return PyLeIsoStream(self._device, cis_handle, self._iso_data_stream)
@staticmethod
def IsoCigEstablished(type):
return Capture(lambda event: True if event.message_type == type else False, PyLeIso._extract_cis_handles)