btle 0.1.4

Lightweight Bluetooth Low Energy Drivers. WIP and very not stable yet!! Designed for https://github.com/AndrewGi/BluetoothMeshRust
Documentation
use crate::hci::command::Command;
use crate::hci::event::{CommandComplete, CommandStatus, ReturnParameters};
use crate::hci::le::{LEControllerOpcode, MetaEventCode};
use crate::hci::{ErrorCode, Opcode};
use crate::le::advertiser::PeerAddressType;
use crate::le::connection::{
    CELength, ConnectionHandle, ConnectionInterval, ConnectionLatency, InitiatorFilterPolicy,
    MasterClockAccuracy, Role, SupervisionTimeout,
};
use crate::le::scan::{OwnAddressType, ScanInterval, ScanWindow};
use crate::{BTAddress, PackError, BT_ADDRESS_LEN};
use core::convert::{TryFrom, TryInto};

#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug, Hash)]
pub struct ReadBufferSizeV1();
impl ReadBufferSizeV1 {
    pub const OPCODE: LEControllerOpcode = LEControllerOpcode::ReadBufferSizeV1;
}
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug, Hash)]
pub struct BufferSizeV1 {
    pub status: ErrorCode,
    pub le_acl_data_packet_len: u16,
    pub total_num_le_acl_data_packets: u8,
}
impl BufferSizeV1 {
    pub const BYTE_LEN: usize = 1 + 2 + 1;
}
impl Command for ReadBufferSizeV1 {
    type Return = CommandComplete<BufferSizeV1>;

    fn opcode() -> Opcode {
        Self::OPCODE.into()
    }

    fn byte_len(&self) -> usize {
        0
    }

    fn pack_into(&self, buf: &mut [u8]) -> Result<(), PackError> {
        PackError::expect_length(0, buf)
    }

    fn unpack_from(buf: &[u8]) -> Result<Self, PackError>
    where
        Self: Sized,
    {
        PackError::expect_length(0, buf)?;
        Ok(ReadBufferSizeV1())
    }
}
impl ReturnParameters for BufferSizeV1 {
    fn byte_len(&self) -> usize {
        Self::BYTE_LEN
    }

    fn pack_into(&self, buf: &mut [u8]) -> Result<(), PackError> {
        PackError::expect_length(Self::BYTE_LEN, buf)?;
        buf[0] = self.status.into();
        buf[1..3].copy_from_slice(&self.le_acl_data_packet_len.to_le_bytes()[..]);
        buf[3] = self.total_num_le_acl_data_packets;
        Ok(())
    }

    fn unpack_from(buf: &[u8]) -> Result<Self, PackError>
    where
        Self: Sized,
    {
        PackError::expect_length(Self::BYTE_LEN, buf)?;
        let status = ErrorCode::try_from(buf[0]).map_err(|_| PackError::bad_index(0))?;
        let le_acl_data_packet_len =
            u16::from_le_bytes((&buf[1..3]).try_into().expect("len checked above"));
        let total_num_le_acl_data_packets = buf[3];
        Ok(BufferSizeV1 {
            status,
            le_acl_data_packet_len,
            total_num_le_acl_data_packets,
        })
    }
}
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug, Hash, Default)]
pub struct ReadBufferSizeV2();
impl ReadBufferSizeV2 {
    pub const OPCODE: LEControllerOpcode = LEControllerOpcode::ReadBufferSizeV2;
}
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug, Hash)]
pub struct BufferSizeV2 {
    pub status: ErrorCode,
    pub le_acl_data_packet_len: u16,
    pub total_num_le_acl_data_packets: u8,
    pub iso_data_packet_len: u16,
    pub total_num_iso_data_packets: u8,
}
impl BufferSizeV2 {
    pub const BYTE_LEN: usize = 1 + 2 + 1 + 2 + 1;
}

impl Command for ReadBufferSizeV2 {
    type Return = CommandComplete<BufferSizeV2>;

    fn opcode() -> Opcode {
        Self::OPCODE.into()
    }

    fn byte_len(&self) -> usize {
        0
    }

    fn pack_into(&self, buf: &mut [u8]) -> Result<(), PackError> {
        PackError::expect_length(0, buf)
    }

    fn unpack_from(buf: &[u8]) -> Result<Self, PackError>
    where
        Self: Sized,
    {
        PackError::expect_length(0, buf)?;
        Ok(ReadBufferSizeV2())
    }
}
impl ReturnParameters for BufferSizeV2 {
    fn byte_len(&self) -> usize {
        Self::BYTE_LEN
    }

    fn pack_into(&self, buf: &mut [u8]) -> Result<(), PackError> {
        PackError::expect_length(Self::BYTE_LEN, buf)?;
        buf[0] = self.status.into();
        buf[1..3].copy_from_slice(&self.le_acl_data_packet_len.to_le_bytes()[..]);
        buf[3] = self.total_num_le_acl_data_packets;
        buf[4..6].copy_from_slice(&self.iso_data_packet_len.to_le_bytes()[..]);
        buf[6] = self.total_num_iso_data_packets;
        Ok(())
    }

    fn unpack_from(buf: &[u8]) -> Result<Self, PackError>
    where
        Self: Sized,
    {
        PackError::expect_length(Self::BYTE_LEN, buf)?;
        let status = ErrorCode::try_from(buf[0]).map_err(|_| PackError::bad_index(0))?;
        let le_acl_data_packet_len =
            u16::from_le_bytes((&buf[1..3]).try_into().expect("len checked above"));
        let total_num_le_acl_data_packets = buf[3];
        let iso_data_packet_len =
            u16::from_le_bytes((&buf[4..6]).try_into().expect("len checked above"));
        let total_num_iso_data_packets = buf[6];
        Ok(BufferSizeV2 {
            status,
            le_acl_data_packet_len,
            total_num_le_acl_data_packets,
            iso_data_packet_len,
            total_num_iso_data_packets,
        })
    }
}
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug, Hash)]
pub struct CreateConnection {
    pub le_scan_interval: ScanInterval,
    pub le_scan_window: ScanWindow,
    pub initiator_filter_policy: InitiatorFilterPolicy,
    pub peer_address_type: PeerAddressType,
    pub peer_address: BTAddress,
    pub own_address_type: OwnAddressType,
    pub connection_interval_min: ConnectionInterval,
    pub connection_interval_max: ConnectionInterval,
    pub connection_latency: ConnectionLatency,
    pub supervision_timeout: SupervisionTimeout,
    pub min_ce_len: CELength,
    pub max_ce_len: CELength,
}
impl CreateConnection {
    pub const OPCODE: LEControllerOpcode = LEControllerOpcode::CreateConnection;
    pub const BYTE_LEN: usize = ScanInterval::BYTE_LEN
        + ScanWindow::BYTE_LEN
        + InitiatorFilterPolicy::BYTE_LEN
        + PeerAddressType::BYTE_LEN
        + BT_ADDRESS_LEN
        + ScanInterval::BYTE_LEN * 2
        + ConnectionLatency::BYTE_LEN
        + SupervisionTimeout::BYTE_LEN
        + CELength::BYTE_LEN * 2;
}
impl Command for CreateConnection {
    type Return = CommandStatus;

    fn opcode() -> Opcode {
        Self::OPCODE.into()
    }

    fn byte_len(&self) -> usize {
        Self::BYTE_LEN
    }

    fn pack_into(&self, buf: &mut [u8]) -> Result<(), PackError> {
        PackError::expect_length(Self::BYTE_LEN, buf)?;
        buf[0..2].copy_from_slice(u16::from(self.le_scan_interval).to_le_bytes().as_ref());
        buf[2..4].copy_from_slice(u16::from(self.le_scan_window).to_le_bytes().as_ref());
        buf[4] = self.initiator_filter_policy.into();
        buf[5] = self.peer_address_type.into();
        buf[6..12].copy_from_slice(self.peer_address.0.as_ref());
        buf[12] = self.own_address_type.into();
        buf[13..15].copy_from_slice(
            u16::from(self.connection_interval_min)
                .to_le_bytes()
                .as_ref(),
        );
        buf[15..17].copy_from_slice(
            u16::from(self.connection_interval_max)
                .to_le_bytes()
                .as_ref(),
        );
        buf[17..19].copy_from_slice(u16::from(self.connection_latency).to_le_bytes().as_ref());
        buf[19..21].copy_from_slice(u16::from(self.supervision_timeout).to_le_bytes().as_ref());
        buf[21..23].copy_from_slice(u16::from(self.min_ce_len).to_le_bytes().as_ref());
        buf[23..25].copy_from_slice(u16::from(self.max_ce_len).to_le_bytes().as_ref());
        Ok(())
    }

    fn unpack_from(buf: &[u8]) -> Result<Self, PackError>
    where
        Self: Sized,
    {
        PackError::expect_length(Self::BYTE_LEN, buf)?;
        todo!("implement unpack from for CreateConnection")
    }
}
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug, Hash)]
pub struct ConnectionCompleteEvent {
    pub status: ErrorCode,
    pub connection_handle: ConnectionHandle,
    pub role: Role,
    pub peer_address_type: PeerAddressType,
    pub peer_address: BTAddress,
    pub connection_interval: ConnectionInterval,
    pub connection_latency: ConnectionLatency,
    pub supervision_timeout: SupervisionTimeout,
    pub master_clock_accuracy: MasterClockAccuracy,
}
impl ConnectionCompleteEvent {
    pub const CODE: MetaEventCode = MetaEventCode::ConnectionComplete;
    pub const BYTE_LEN: usize = ErrorCode::BYTE_LEN
        + ConnectionHandle::BYTE_LEN
        + Role::BYTE_LEN
        + PeerAddressType::BYTE_LEN
        + BT_ADDRESS_LEN
        + ConnectionInterval::BYTE_LEN
        + ConnectionLatency::BYTE_LEN
        + SupervisionTimeout::BYTE_LEN
        + MasterClockAccuracy::BYTE_LEN;
}