From 90d31c0f8f461823a7d62d9bbe003db6d6cd845c Mon Sep 17 00:00:00 2001 From: GhaithOueslati Date: Mon, 1 Jan 2024 18:30:10 +0100 Subject: [PATCH] feat(LE commad): add Host Buffer Size commad --- src/host/mod.rs | 86 ++++++++++++++++++++++++++++++++++++++++++++++--- src/opcode.rs | 1 + 2 files changed, 83 insertions(+), 4 deletions(-) diff --git a/src/host/mod.rs b/src/host/mod.rs index 0b6eb7a..61d0ba2 100644 --- a/src/host/mod.rs +++ b/src/host/mod.rs @@ -190,25 +190,46 @@ pub trait HostHci { /// sent in the direction from the Controller to the Host. /// /// If the flow control is turned off, the Host should not send the - /// [Host Number of Completed Packets](HostHci::host_number_of_completed_packets) command. + /// [Number of Completed Packets](HostHci::number_of_completed_packets) command. /// That command will be ignored by the Controller it is sent by the Host and flow control is /// off. /// /// If flow control is turned on for HCI ACL Data Packets and off for HCI synchronous - /// Data Packets, [Host Number of Completed Packets](HostHci::host_number_of_completed_packets) + /// Data Packets, [Number of Completed Packets](HostHci::number_of_completed_packets) /// commands sent by the Host should only contain [Connection Handles](ConnectionHandle) /// for ACL connections. /// /// If flow control is turned off for HCI ACL Data Packets and on for HCI synchronous Data Packets, - /// [Host Number of Completed Packets](HostHci::host_number_of_completed_packets) commands sent + /// [Number of Completed Packets](HostHci::number_of_completed_packets) commands sent /// by the Host should only contain [Connection Handles](ConnectionHandle) for synchronous connections. /// /// If flow control is turned on for HCI ACL Data Packets and HCI synchronous Data Packets, - /// the Host will send [Host Number of Completed Packets](HostHci::host_number_of_completed_packets) + /// the Host will send [Number of Completed Packets](HostHci::number_of_completed_packets) /// commands both for ACL connections and synchronous connections. /// The [Flow Control](FlowControl) parameter shall only be changed if no connections exist. async fn set_controller_to_host_flow_control(&mut self, flow_control: FlowControl); + /// This command is used by the Host to notify the Controller about the Maximum size of the data portion + /// of HCI ACL and Synchronous Sata Packets sent from the controller to the Host. + /// + /// The Controller shal segment the data to be transmitted from the Controller to the Host according + /// to these sizes, so that the HCI Data Packets will contain data with up to these sizes. + /// + /// This command also notifies the Controller about the total number of HCI ACL and Synchronous Data Packets + /// that can be storede in the data buffers of the Host. + /// + /// If flow control from the Controller to the Host is turned off, and this command has not been issued + /// by the Host, this means the controller will send HCI Data Packets to the Host with any lengths the + /// Controlller wants to use, and it is assumed that the data buffer sizes of the Host are unlimited. + /// + /// If flow control from the Controller to the Host is turned on, this command shall after a power-on + /// or a reset always be sent by the Host before the first + /// [Number of Completed Packets](HostHci::number_of_completed_packets) command is sent. + /// + /// The [Set Controller to Host Flow Control](HostHci::set_controller_to_host_flow_control) commad + /// is used to turn flow control on or off. + async fn host_buffer_size(&mut self, params: HostBufferSize); + /// This command reads the values for the version information for the local Controller. /// /// Defined in Bluetooth Specification Vol 2, Part E, Section 7.4.1. @@ -1185,6 +1206,13 @@ where .await; } + async fn host_buffer_size(&mut self, params: HostBufferSize) { + let mut bytes = [0; 6]; + params.copy_into_slice(&mut bytes); + self.controller_write(crate::opcode::HOST_BUFFER_SIZE, &bytes) + .await; + } + async fn read_local_version_information(&mut self) { self.controller_write(crate::opcode::READ_LOCAL_VERSION_INFO, &[]) .await; @@ -1710,6 +1738,56 @@ pub enum FlowControl { Both = 0x03, } +#[derive(Copy, Clone, Debug)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +/// Parameters for the [host_buffer_size](HostHci::host_buffer_size) commad +/// +/// # Note: +/// The [Host ACL Data Packet Length](HostBufferSize::acl_data_packet_length) and +/// [Host Synchronous Data Packet Length](HostBufferSize::sync_data_packet_length) command parameters +/// do not include the length of the HCI Data Packet header. +/// +/// See Bluetooth spec. v.5.4 [Vol 4, Part E, 7.3.39]. +pub struct HostBufferSize { + /// Maximum length (in octets) of the data portion of each HCI ACL Data Packet that the host is able + /// to accept. + /// + /// this parameter will be used to determine the size of the L2CAP segments contained in the ACL Data + /// Packets, which are transferred from the Controller to the Host. + /// + /// Values: + /// - 251 .. 65535 + pub acl_data_packet_length: u16, + /// Maximum length (in octets) of the data portion of each HCI Synchronous Data Packet that the Host + /// is able to accept. `NOT USED` + /// + /// This parameter is used to determine the maximum size of HCI Synchronous Data Packets. Both the Host + /// and the Controller shall support command and event packets, zhere the data portion (excluding header) + /// contained in the packet is 255 octets is size. + pub sync_data_packet_length: u8, + /// The total number of HCI ACL Data Packets that can be stored in the data buffers of the Host. + /// + /// This parameter contains the total number of HCI ACL Data Packets that can be stored in the data buffers + /// of the Host. The Controller will determine how the buffers are to be divided between different + /// [Connection Handles](ConnectionHandle). + pub total_acl_data_packets: u16, + /// Total number of HCI Synchronous Data Packets that can be stored in the data buffers of the Host. `NOT USED` + /// + /// This parameter gives the save information for HCI Synchronous Data Packets. + pub total_sync_data_packets: u16, +} + +impl HostBufferSize { + fn copy_into_slice(&self, bytes: &mut [u8]) { + assert_eq!(bytes.len(), 6); + + LittleEndian::write_u16(&mut bytes[0..], self.acl_data_packet_length); + bytes[2] = self.sync_data_packet_length; + LittleEndian::write_u16(&mut bytes[3..], self.total_acl_data_packets); + LittleEndian::write_u16(&mut bytes[5..], self.total_sync_data_packets); + } +} + #[cfg(not(feature = "defmt"))] bitflags::bitflags! { /// Event flags defined for the [`le_set_event_mask`](HostHci::le_set_event_mask) command. diff --git a/src/opcode.rs b/src/opcode.rs index bb6a692..7fb5e1d 100644 --- a/src/opcode.rs +++ b/src/opcode.rs @@ -50,6 +50,7 @@ opcodes! { pub const RESET = 0x0003; pub const READ_TX_POWER_LEVEL = 0x002D; pub const SET_CONTROLLER_TO_HOST_FLOW_CONTROL = 0x031; + pub const HOST_BUFFER_SIZE = 0x033; } InfoParam = 0x0004;