# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you 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 import asyncio import struct import hci import sys import time async def wait_ev(ev): while ev.is_set() == False: await asyncio.sleep(0.000001) async def wait_for_event(ev, timeout): try: await asyncio.wait_for(wait_ev(ev), timeout) except TimeoutError as e: logging.error(f"Timeout waiting for event: {e}") sys.exit() class HCI_Commands(): def __init__(self, send=None, rx_buffer_q=None, asyncio_loop=None, tp=None, device_mode="rx"): self.hci_send_cmd = hci.HCI_Cmd_Send() self.hci_send_acl_data = hci.HCI_ACL_Data_Send() self.hci_recv_ev_packet = hci.HCI_Recv_Event_Packet() self.async_sem_cmd = asyncio.Semaphore() self.async_ev_cmd_end = asyncio.Event() self.async_ev_connected = asyncio.Event() self.async_ev_encryption_change = asyncio.Event() self.async_ev_set_data_len = asyncio.Event() self.async_ev_update_phy = asyncio.Event() self.async_ev_num_cmp_pckts = asyncio.Event() self.async_ev_recv_data_finish = asyncio.Event() self.async_ev_rx_wait_finish = asyncio.Event() self.async_lock_packets_cnt = asyncio.Lock() self.valid_recv_data = 0 self.expected_recv_data = 0 self.last_timestamp = 0 self.sent_packets_counter = 0 self.send = send self.rx_buffer_q = rx_buffer_q self.tp = tp self.loop = asyncio_loop self.device_mode = device_mode async def rx_buffer_q_wait(self): try: logging.debug("%s", self.rx_buffer_q_wait.__name__) while not self.async_ev_rx_wait_finish.is_set(): if self.rx_buffer_q.empty(): await asyncio.sleep(0.000000001) continue await self.loop.create_task(self.recv_handler()) logging.info("rx_buffer_q_wait finished") self.async_ev_rx_wait_finish.clear() except asyncio.CancelledError: logging.critical("rx_buffer_q_wait task canceled") """ 7.3 Controller & Baseband commands """ async def cmd_set_event_mask(self, mask: int = 0x00001fffffffffff): async with self.async_sem_cmd: self.hci_send_cmd.set(hci.OGF_HOST_CTL, hci.OCF_SET_EVENT_MASK, struct.pack(' int: current_ev_name = type( self.hci_recv_ev_packet.current_event).__name__ if current_ev_name == type(hci.HCI_Ev_Cmd_Complete()).__name__: return struct.unpack_from( " hci.max_data_len.supported_max_tx_octets - hci.L2CAP_HDR_BYTES): logging.critical( f"Number of data bytes to send + 4 bytes of L2CAP header: {hci.num_of_bytes_to_send + 4} " f"exceeds allowed value of: {hci.max_data_len.supported_max_tx_octets}. Closing.") raise SystemExit( f"Number of data bytes to send + 4 bytes of L2CAP header: {hci.num_of_bytes_to_send + 4} " f"exceeds allowed value of: {hci.max_data_len.supported_max_tx_octets}. Closing.") return status() elif ocf == hci.OCF_LE_READ_PHY: hci.phy = hci.LE_Read_PHY() hci.phy.set(*struct.unpack('> 12 bc_flag = (handle_pb_bc_flags & 0xC000) >> 14 hci_recv_acl_data_packet = hci.HCI_Recv_ACL_Data_Packet() if pb_flag == 0b10: l2cap_data = hci.HCI_Recv_L2CAP_Data() data = buffer[5:] l2cap_data.set(*struct.unpack(" self.tp.sample_time \ # or packet_number == 0 \ # or packet_number == self.tp.total_packets_number-1: # self.tp.record_throughput(packet_number, timestamp) # self.last_timestamp = timestamp if packet_number >= self.tp.total_packets_number - 1: self.async_ev_recv_data_finish.set() def handle_acl_data(self, buffer: bytes, timestamp: int): hci_recv_acl_data_packet = self.parse_acl_data(buffer) logging.debug("%s", hci_recv_acl_data_packet) recv_data_type = type(hci_recv_acl_data_packet.data).__name__ if recv_data_type == 'HCI_Recv_L2CAP_Data': self.match_recv_l2cap_data(buffer, timestamp) async def recv_handler(self): while not self.rx_buffer_q.empty(): q_buffer_item, q_timestamp = self.rx_buffer_q.get() packet_type = struct.unpack('