Skip to content

Commit

Permalink
feat(LE commad): add Host Buffer Size commad
Browse files Browse the repository at this point in the history
  • Loading branch information
OueslatiGhaith committed Jan 1, 2024
1 parent 37e4223 commit 90d31c0
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 4 deletions.
86 changes: 82 additions & 4 deletions src/host/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions src/opcode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 90d31c0

Please sign in to comment.