Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V1.17.0 #6

Merged
merged 27 commits into from
Jan 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
1733ff9
feat(vendor event): Gatt EATT Bearer event
OueslatiGhaith Dec 28, 2023
ab3aa7e
feat(vendor event): add L2CAP COC Connect event
OueslatiGhaith Dec 28, 2023
7ecc075
feat(vendor event): add L2CAP COC Connect Cofirm event
OueslatiGhaith Dec 28, 2023
3123ced
feat(vendor event): add L2CAP COC Reconfig event
OueslatiGhaith Dec 28, 2023
ca8a20c
feat(vendor event): add L2CAP COC Reconfig Confirm event
OueslatiGhaith Dec 29, 2023
3d90ebd
feat(vendor event): add L2CAP COC Disconnect event
OueslatiGhaith Dec 29, 2023
ac6dc5f
feat(vendor event): add L2CAP COC Flow Control event
OueslatiGhaith Dec 29, 2023
aed2076
feat(vendor event): add L2CAP COC Rx Data event
OueslatiGhaith Dec 29, 2023
2b60a93
feat(vendor L2CAP command): added L2CAP COC Connect command
OueslatiGhaith Dec 29, 2023
bc01b80
feat(vendor L2CAP command): added L2CAP COC Connect Confirm command
OueslatiGhaith Dec 29, 2023
c1b72fe
feat(vendor L2CAP command): added L2CAP COC Reconfig command
OueslatiGhaith Dec 29, 2023
0f83bab
feat(vendor L2CAP command): added L2CAP COC Reconfig Confirm command
OueslatiGhaith Dec 29, 2023
e8830b0
feat(vendor L2CAP command): added L2CAP COC Disconnect command
OueslatiGhaith Dec 29, 2023
9c9c5a6
feat(vendor L2CAP command): added L2CAP COC Flow Control command
OueslatiGhaith Dec 29, 2023
1798b4d
feat(vendor L2CAP command): added L2CAP COC Tx Data command
OueslatiGhaith Dec 29, 2023
6178a11
feat(vendor event): add L2CAP COC Tx Pool Available event
OueslatiGhaith Dec 29, 2023
452c1fe
feat(vendor event): add GATT multi notification event
OueslatiGhaith Dec 29, 2023
2ccee60
feat(vendor event): add GATT Notification Complete event
OueslatiGhaith Dec 30, 2023
1e08cc6
feat(vendor event): add GATT Read Ext event
OueslatiGhaith Dec 30, 2023
036841c
feat(vendor event): add GATT Indication Ext event
OueslatiGhaith Dec 30, 2023
ea9f37d
feat(vendor event): add GATT Notification Ext event
OueslatiGhaith Dec 30, 2023
7b351d4
doc: Connection Handle range for Enhanced ATT bearer now ends at 0xEA3F
OueslatiGhaith Dec 30, 2023
1a20bd3
feat(vendor GATT commands): added Notify Notification Complete charac…
OueslatiGhaith Dec 30, 2023
e3160a7
doc: HAL set config data parameters are updated
OueslatiGhaith Dec 30, 2023
37e4223
feat(LE command): add Set Controller To Host Flow Control command
OueslatiGhaith Dec 30, 2023
90d31c0
feat(LE commad): add Host Buffer Size commad
OueslatiGhaith Jan 1, 2024
4142105
feat(LE command): add Number of Completed Packets command
OueslatiGhaith Jan 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
/target
**/*.rs.bk
Cargo.lock
justfile
28 changes: 25 additions & 3 deletions src/event/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -596,15 +596,15 @@ fn to_hardware_error(payload: &[u8]) -> Result<HardwareError, Error> {
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct NumberOfCompletedPackets {
/// Number of connection handles whose data is sent in this event.
num_handles: usize,
pub(crate) num_handles: usize,

/// Data buffer for the event.
data_buf: [u8; NUMBER_OF_COMPLETED_PACKETS_MAX_LEN],
pub(crate) data_buf: [u8; NUMBER_OF_COMPLETED_PACKETS_MAX_LEN],
}

// The maximum number of bytes in the buffer is the max HCI packet size (255) less the other data in
// the packet.
const NUMBER_OF_COMPLETED_PACKETS_MAX_LEN: usize = 254;
pub(crate) const NUMBER_OF_COMPLETED_PACKETS_MAX_LEN: usize = 254;

impl Debug for NumberOfCompletedPackets {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
Expand All @@ -617,6 +617,28 @@ impl Debug for NumberOfCompletedPackets {
}

impl NumberOfCompletedPackets {
pub fn new(items: impl Iterator<Item = NumberOfCompletedPacketsPair>) -> Self {
let mut data_buf = [0; NUMBER_OF_COMPLETED_PACKETS_MAX_LEN];

// let num_handles = &items.count();
let mut index = 0;
let mut num_handles = 0;
for item in items {
LittleEndian::write_u16(&mut data_buf[index..], item.conn_handle.0);
LittleEndian::write_u16(
&mut data_buf[index + 2..],
item.num_completed_packets as u16,
);
index += 4;
num_handles += 1;
}

Self {
num_handles,
data_buf,
}
}

/// Returns an iterator over the connection handle-number of completed packet pairs.
pub fn iter(&self) -> NumberOfCompletedPacketsIterator {
NumberOfCompletedPacketsIterator {
Expand Down
171 changes: 171 additions & 0 deletions src/host/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
//! support sending the packet ID, as `uart` does. In that case, it would make sense to also remove
//! `uart` and move its contents up one level.

use crate::event::{NumberOfCompletedPackets, NUMBER_OF_COMPLETED_PACKETS_MAX_LEN};
use crate::ConnectionHandle;
use byteorder::{ByteOrder, LittleEndian};
use core::convert::Into;
Expand Down Expand Up @@ -186,6 +187,81 @@ pub trait HostHci {
power_level_type: TxPowerLevel,
);

/// This command is used by the Host to turn flow control on and off for data and/or voice
/// sent in the direction from the Controller to the Host.
///
/// If the flow control is turned off, the Host should not send the
/// [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, [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,
/// [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 [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 is used by the Host to indicate to the Controller the number of HCI Data Packets
/// that have been completed for each [Connection Handle](ConnectionHandle) since the previous
/// [Number of Completed Packets](HostHci::number_of_completed_packets) command was sent to
/// the Controller. This means that the corresponding buffer space has been freed in the Host.
///
/// Based on this information, and the
/// [Total Number of ACL Data Packets](HostBufferSize::total_acl_data_packets) and
/// [Total Number of Synchronous Data Packets](HostBufferSize::total_sync_data_packets)
/// parameters of the [Host Buffer Size](HostHci::host_buffer_size) command, the Controller can
/// determine for which [Connection Handles](ConnectionHandle) the following HCI Data Packets
/// should be sent to the Host.
///
/// The command should only be issued by the Host if flow control in the direction from the Controller
/// to the host is on and there is at least one connection, or if the Controller is in local loopback
/// mode. Otherwise, the command will will be ignored by the Controller.
///
/// When the Host has completed one or more HCI Data Packet(s) it shall send a
/// [Number of Completed Packets](HostHci::number_of_completed_packets) command to the Controller,
/// unitl it finally reports that all pending HCI Data Packets have been completed. The frequency
/// at which this command is sent.
///
/// # Note:
/// This command is a special command in the sense that no event is normally generated after the
/// command has completed. The command may be sent at any time by the Host when there is at leat
/// one connection, or if the Controller is in local loopback mode independent of other commands.
/// The normal flow control for commands is not used for the
/// [Number of Complete Packets](HostHci::number_of_completed_packets) command.
///
/// See Bluetooth spec. v.5.4 [Vol 4, Part E, 7.3.40].
async fn number_of_completed_packets(&mut self, params: NumberOfCompletedPackets);

/// 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 @@ -1154,6 +1230,29 @@ where
.await;
}

async fn set_controller_to_host_flow_control(&mut self, flow_control: FlowControl) {
self.controller_write(
crate::opcode::SET_CONTROLLER_TO_HOST_FLOW_CONTROL,
&[flow_control as u8],
)
.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 number_of_completed_packets(&mut self, params: NumberOfCompletedPackets) {
let mut bytes = [0; NUMBER_OF_COMPLETED_PACKETS_MAX_LEN + 1];
bytes[0] = params.num_handles as u8;
bytes[1..].copy_from_slice(&params.data_buf);
self.controller_write(crate::opcode::NUMBER_OF_COMPLETED_PACKETS, &bytes)
.await;
}

async fn read_local_version_information(&mut self) {
self.controller_write(crate::opcode::READ_LOCAL_VERSION_INFO, &[])
.await;
Expand Down Expand Up @@ -1657,6 +1756,78 @@ pub enum TxPowerLevel {
Maximum = 0x01,
}

/// For the [set_controller_to_host_flow_control](HostHci::set_controller_to_host_flow_control) command, the
/// allowed values for flow control.
///
/// See Bluetooth spec. v.5.4 [Vol 4, Part E, 7.3.38].
#[repr(u8)]
#[derive(Copy, Clone, Debug, PartialEq, Default)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum FlowControl {
/// Flow control off in direction from controller to host. `default`
#[default]
Off = 0x00,
/// Flow control on for HCI ACL Data Packets and off for HCI synchronous.
/// Data Packets in direction from Controller to Host.
HciAclDataOnly = 0x01,
/// Flow control off for HCI ACL Data Packets and on for HCI synchronous.
/// Data Packets in direction from Controller to Host.
HciSyncDataOnly = 0x02,
/// control on both for HCI ACL Data Packets and HCI synchronous.
/// Data Packets in direction from Controller to Host.
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
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ impl core::convert::From<Status> for u8 {
///
/// Values:
/// - 0x0000 .. 0xEFFF: Unenhanced ATT bearer
/// - 0xEA00 .. 0xEA1F: Enhanced ATT bearer (the LSB-byte of the parameter is
/// - 0xEA00 .. 0xEA3F: Enhanced ATT bearer (the LSB-byte of the parameter is
/// the connection oriented channel index)
#[derive(Clone, Copy, Debug, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
Expand Down
3 changes: 3 additions & 0 deletions src/opcode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ opcodes! {
pub const SET_EVENT_MASK = 0x0001;
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;
pub const NUMBER_OF_COMPLETED_PACKETS = 0x035;
}

InfoParam = 0x0004;
Expand Down
6 changes: 6 additions & 0 deletions src/vendor/command/gatt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1516,6 +1516,9 @@ bitflags::bitflags! {
/// The application will be notified when a read request of any type is got for this
/// attribute.
const CONFIRM_READ = 0x04;

/// The application will be notified when a notification is complete
const NOTIFY_NOTIFICATION_COMPLETE = 0x08;
}
}

Expand All @@ -1533,6 +1536,9 @@ defmt::bitflags! {
/// The application will be notified when a read request of any type is got for this
/// attribute.
const CONFIRM_READ = 0x04;

/// The application will be notified when a notification is complete
const NOTIFY_NOTIFICATION_COMPLETE = 0x08;
}
}

Expand Down
8 changes: 6 additions & 2 deletions src/vendor/command/hal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,11 +224,15 @@ pub struct ConfigData {
///- 0x00: CONFIG_DATA_PUBADDR_OFFSET;
/// Bluetooth public address; 6 bytes
///- 0x08: CONFIG_DATA_ER_OFFSET;
/// Encryption root key used to derive LTK and CSRK; 16 bytes
/// Encryption root key used to derive LTK (legacy) and CSRK; 16 bytes
///- 0x18: CONFIG_DATA_IR_OFFSET;
/// Identity root key used to derive LTK and CSRK; 16 bytes
/// Identity root key used to derive DHK (legacy) and IRK; 16 bytes
///- 0x2E: CONFIG_DATA_RANDOM_ADDRESS_OFFSET;
/// Static Random Address; 6 bytes
///- 0x34: CONFIG_DATA_GAP_ADD_REC_NBR_OFFSET;
/// GAP service additional record number; 1 byte
///- 0x35: CONFIG_DATA_SC_KEY_TYPE_OFFSET;
/// Secure Connection key type (0: "normal", 1: "debug"); 1 byte
///- 0xB0: CONFIG_DATA_SMP_MODE_OFFSET;
/// SMP mode (0: "normal", 1: "bypass", 2: "no blacklist"); 1 byte
///- 0xC0: CONFIG_DATA_LL_SCAN_CHAN_MAP_OFFSET (only for STM32WB);
Expand Down
Loading