btle/hci/le/
mod.rs

1//! HCI LE Layer. Handles everything from advertising, scanning, LE links, etc.
2pub mod advertise;
3pub mod mask;
4pub mod messages;
5pub mod report;
6pub use messages::*;
7pub mod connection;
8pub mod random;
9pub mod scan;
10use crate::bytes::Storage;
11use crate::hci::event::{Event, EventCode, EventPacket};
12use crate::hci::{Opcode, OCF, OGF};
13use crate::ConversionError;
14use crate::PackError;
15use core::convert::TryFrom;
16
17/// OCF LE Controller code.
18#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)]
19#[repr(u16)]
20pub enum LEControllerOpcode {
21    SetEventMask = 0x0001,
22    ReadBufferSizeV1 = 0x0002,
23    ReadBufferSizeV2 = 0x0060,
24    ReadLocalSupportedFeatures = 0x0003,
25    SetRandomAddress = 0x0005,
26    SetAdvertisingParameters = 0x0006,
27    ReadAdvertisingChannelTxPower = 0x0007,
28    SetAdvertisingData = 0x0008,
29    SetScanResponseData = 0x0009,
30    SetAdvertisingEnable = 0x000A,
31    SetScanParameters = 0x000B,
32    SetScanEnable = 0x000C,
33    CreateConnection = 0x000D,
34    CreateConnectionCancel = 0x000E,
35    ReadWhitelistSize = 0x000F,
36    ClearWhitelist = 0x0010,
37    AddDeviceToWhitelist = 0x0011,
38    RemoveDeviceFromWhitelist = 0x0012,
39    ConnectionUpdate = 0x0013,
40    SetHostChannelClassification = 0x0014,
41    ReadChannelMap = 0x0015,
42    ReadRemoteUsedFeatures = 0x0016,
43    Encrypt = 0x0017,
44    Rand = 0x0018,
45    StartEncryption = 0x0019,
46    LongTermKeyRequestReply = 0x001A,
47    LongTermKeyRequestNegativeReply = 0x001B,
48    ReadSupportedState = 0x001C,
49    ReceiverTest = 0x001D,
50    TransmitterTest = 0x001E,
51    TestEnd = 0x001F,
52}
53impl TryFrom<OCF> for LEControllerOpcode {
54    type Error = ConversionError;
55
56    fn try_from(ocf: OCF) -> Result<Self, Self::Error> {
57        match u16::from(ocf) {
58            0x0001 => Ok(LEControllerOpcode::SetEventMask),
59            0x0060 => Ok(LEControllerOpcode::ReadBufferSizeV1),
60            0x0002 => Ok(LEControllerOpcode::ReadBufferSizeV2),
61            0x0003 => Ok(LEControllerOpcode::ReadLocalSupportedFeatures),
62            0x0005 => Ok(LEControllerOpcode::SetRandomAddress),
63            0x0006 => Ok(LEControllerOpcode::SetAdvertisingParameters),
64            0x0007 => Ok(LEControllerOpcode::ReadAdvertisingChannelTxPower),
65            0x0008 => Ok(LEControllerOpcode::SetAdvertisingData),
66            0x0009 => Ok(LEControllerOpcode::SetScanResponseData),
67            0x000A => Ok(LEControllerOpcode::SetAdvertisingEnable),
68            0x000B => Ok(LEControllerOpcode::SetScanParameters),
69            0x000C => Ok(LEControllerOpcode::SetScanEnable),
70            0x000D => Ok(LEControllerOpcode::CreateConnection),
71            0x000E => Ok(LEControllerOpcode::CreateConnectionCancel),
72            0x000F => Ok(LEControllerOpcode::ReadWhitelistSize),
73            0x0010 => Ok(LEControllerOpcode::ClearWhitelist),
74            0x0011 => Ok(LEControllerOpcode::AddDeviceToWhitelist),
75            0x0012 => Ok(LEControllerOpcode::RemoveDeviceFromWhitelist),
76            0x0013 => Ok(LEControllerOpcode::ConnectionUpdate),
77            0x0014 => Ok(LEControllerOpcode::SetHostChannelClassification),
78            0x0015 => Ok(LEControllerOpcode::ReadChannelMap),
79            0x0016 => Ok(LEControllerOpcode::ReadRemoteUsedFeatures),
80            0x0017 => Ok(LEControllerOpcode::Encrypt),
81            0x0018 => Ok(LEControllerOpcode::Rand),
82            0x0019 => Ok(LEControllerOpcode::StartEncryption),
83            0x001A => Ok(LEControllerOpcode::LongTermKeyRequestReply),
84            0x001B => Ok(LEControllerOpcode::LongTermKeyRequestNegativeReply),
85            0x001C => Ok(LEControllerOpcode::ReadSupportedState),
86            0x001D => Ok(LEControllerOpcode::ReceiverTest),
87            0x001E => Ok(LEControllerOpcode::TransmitterTest),
88            0x001F => Ok(LEControllerOpcode::TestEnd),
89            _ => Err(ConversionError(())),
90        }
91    }
92}
93impl LEControllerOpcode {
94    pub const fn ogf() -> OGF {
95        OGF::LEController
96    }
97}
98impl From<LEControllerOpcode> for OCF {
99    fn from(opcode: LEControllerOpcode) -> Self {
100        OCF::new(opcode as u16)
101    }
102}
103impl From<LEControllerOpcode> for Opcode {
104    fn from(opcode: LEControllerOpcode) -> Self {
105        Opcode(OGF::LEController, opcode.into())
106    }
107}
108/// LE Meta Event code. Similar to `EventCode` but just for LE events.
109#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug, Hash)]
110pub enum MetaEventCode {
111    ConnectionComplete = 0x01,
112    AdvertisingReport = 0x02,
113    ConnectionUpdateComplete = 0x03,
114    ReadRemoteFeatures = 0x04,
115    LongTermKeyRequest = 0x05,
116    RemoteConnectionParametersRequest = 0x06,
117    DataLengthChange = 0x07,
118    ReadLocalP256PublicKeyComplete = 0x08,
119    GenerateDHKeyComplete = 0x09,
120    EnhancedConnectionComplete = 0x0A,
121    DirectedAdvertisingReport = 0x0B,
122    PHYUpdateCompleteEvent = 0x0C,
123    ExtendedAdvertisingReport = 0x0D,
124    PeriodicAdvertisingSyncEstablished = 0x0E,
125    PeriodicAdvertisingReport = 0x0F,
126    PeriodicAdvertisingSyncLost = 0x10,
127    ScanTimeout = 0x11,
128    AdvertisingSetTerminated = 0x12,
129    ScanRequestReceived = 0x13,
130    ChannelSelectionAlgorithm = 0x14,
131    ConnectionlessIQReport = 0x15,
132    ConnectionIQReport = 0x16,
133    CTERequestFailed = 0x17,
134    PeriodicAdvertisingSyncTransferReceived = 0x18,
135    CISEstablished = 0x19,
136    CISRequest = 0x1A,
137    CreateBIGComplete = 0x1B,
138    TerminateBIGComplete = 0x1C,
139    BIGSyncEstablished = 0x1D,
140    BIGSyncLost = 0x1E,
141    RequestPeerSCAComplete = 0x1F,
142    PathLossThreshold = 0x20,
143    TransmitPowerReporting = 0x21,
144    BIGInfoAdvertisingReport = 0x22,
145}
146impl MetaEventCode {
147    /// The `MetaEventCode` with the highest value.
148    pub const MAX_CODE: MetaEventCode = MetaEventCode::BIGInfoAdvertisingReport;
149}
150impl From<MetaEventCode> for u8 {
151    fn from(c: MetaEventCode) -> Self {
152        c as u8
153    }
154}
155impl TryFrom<u8> for MetaEventCode {
156    type Error = ConversionError;
157
158    fn try_from(value: u8) -> Result<Self, Self::Error> {
159        match value {
160            0x01 => Ok(MetaEventCode::ConnectionComplete),
161            0x02 => Ok(MetaEventCode::AdvertisingReport),
162            0x03 => Ok(MetaEventCode::ConnectionUpdateComplete),
163            0x04 => Ok(MetaEventCode::ReadRemoteFeatures),
164            0x05 => Ok(MetaEventCode::LongTermKeyRequest),
165            0x06 => Ok(MetaEventCode::RemoteConnectionParametersRequest),
166            0x07 => Ok(MetaEventCode::DataLengthChange),
167            0x08 => Ok(MetaEventCode::ReadLocalP256PublicKeyComplete),
168            0x09 => Ok(MetaEventCode::GenerateDHKeyComplete),
169            0x0A => Ok(MetaEventCode::EnhancedConnectionComplete),
170            0x0B => Ok(MetaEventCode::DirectedAdvertisingReport),
171            0x0C => Ok(MetaEventCode::PHYUpdateCompleteEvent),
172            0x0D => Ok(MetaEventCode::ExtendedAdvertisingReport),
173            0x0E => Ok(MetaEventCode::PeriodicAdvertisingSyncEstablished),
174            0x0F => Ok(MetaEventCode::PeriodicAdvertisingReport),
175            0x10 => Ok(MetaEventCode::PeriodicAdvertisingSyncLost),
176            0x11 => Ok(MetaEventCode::ScanTimeout),
177            0x12 => Ok(MetaEventCode::AdvertisingSetTerminated),
178            0x13 => Ok(MetaEventCode::ScanRequestReceived),
179            0x14 => Ok(MetaEventCode::ChannelSelectionAlgorithm),
180            0x15 => Ok(MetaEventCode::ConnectionlessIQReport),
181            0x16 => Ok(MetaEventCode::ConnectionIQReport),
182            0x17 => Ok(MetaEventCode::CTERequestFailed),
183            0x18 => Ok(MetaEventCode::PeriodicAdvertisingSyncTransferReceived),
184            0x19 => Ok(MetaEventCode::CISEstablished),
185            0x1A => Ok(MetaEventCode::CISRequest),
186            0x1B => Ok(MetaEventCode::CreateBIGComplete),
187            0x1C => Ok(MetaEventCode::TerminateBIGComplete),
188            0x1D => Ok(MetaEventCode::BIGSyncEstablished),
189            0x1E => Ok(MetaEventCode::BIGSyncLost),
190            0x1F => Ok(MetaEventCode::RequestPeerSCAComplete),
191            0x20 => Ok(MetaEventCode::PathLossThreshold),
192            0x21 => Ok(MetaEventCode::TransmitPowerReporting),
193            0x22 => Ok(MetaEventCode::BIGInfoAdvertisingReport),
194            _ => Err(ConversionError(())),
195        }
196    }
197}
198/// Bluetooth Low Energy Meta Event. Just like a regular event (with a event code of
199/// `EventCode::LEMeta`) but with an extra `META_CODE` field (1 byte) that allows for multiple
200/// LE Meta events.
201pub trait MetaEvent {
202    const META_CODE: MetaEventCode;
203    fn meta_byte_len(&self) -> usize;
204    fn meta_unpack_from(buf: &[u8]) -> Result<Self, PackError>
205    where
206        Self: Sized;
207    fn meta_unpack_packet(packet: RawMetaEvent<&[u8]>) -> Result<Self, PackError>
208    where
209        Self: Sized,
210    {
211        if Self::META_CODE != packet.code {
212            Err(PackError::BadOpcode)
213        } else {
214            Self::meta_unpack_from(packet.parameters)
215        }
216    }
217    fn meta_pack_into(&self, buf: &mut [u8]) -> Result<(), PackError>;
218}
219#[derive(Copy, Clone)]
220pub struct RawMetaEvent<Buf> {
221    pub code: MetaEventCode,
222    pub parameters: Buf,
223}
224impl<Buf: AsRef<[u8]>> core::fmt::Debug for RawMetaEvent<Buf> {
225    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
226        f.debug_struct("RawMetaEvent<Buf>")
227            .field("code", &self.code)
228            .field("parameters", &self.parameters.as_ref())
229            .finish()
230    }
231}
232impl<Buf: AsRef<[u8]>> RawMetaEvent<Buf> {
233    pub fn as_ref(&self) -> RawMetaEvent<&'_ [u8]> {
234        RawMetaEvent {
235            code: self.code,
236            parameters: self.parameters.as_ref(),
237        }
238    }
239    pub fn to_owned<NewBuf: Storage<u8>>(&self) -> RawMetaEvent<NewBuf> {
240        RawMetaEvent {
241            code: self.code,
242            parameters: NewBuf::from_slice(self.parameters.as_ref()),
243        }
244    }
245}
246impl<'a> TryFrom<EventPacket<&'a [u8]>> for RawMetaEvent<&'a [u8]> {
247    type Error = PackError;
248
249    fn try_from(value: EventPacket<&'a [u8]>) -> Result<Self, Self::Error> {
250        if value.event_code != EventCode::LEMeta {
251            return Err(PackError::BadOpcode);
252        }
253        let code =
254            MetaEventCode::try_from(*value.parameters.get(0).ok_or(PackError::BadLength {
255                expected: 1,
256                got: 0,
257            })?)
258            .map_err(|_| PackError::BadOpcode)?;
259        Ok(RawMetaEvent {
260            code,
261            parameters: &value.parameters[1..],
262        })
263    }
264}
265impl<M: MetaEvent> Event for M {
266    const EVENT_CODE: EventCode = EventCode::LEMeta;
267
268    fn event_byte_len(&self) -> usize {
269        MetaEvent::meta_byte_len(self) + 1
270    }
271
272    fn event_unpack_from(buf: &[u8]) -> Result<Self, PackError>
273    where
274        Self: Sized,
275    {
276        if u8::from(Self::META_CODE)
277            == *buf.get(0).ok_or(PackError::BadLength {
278                expected: 1,
279                got: 0,
280            })?
281        {
282            MetaEvent::meta_unpack_from(&buf[1..])
283        } else {
284            Err(PackError::bad_index(0))
285        }
286    }
287
288    fn event_pack_into(&self, buf: &mut [u8]) -> Result<(), PackError> {
289        PackError::expect_length(self.meta_byte_len() + 1, buf)?;
290        <Self as MetaEvent>::meta_pack_into(self, &mut buf[1..])?;
291        buf[0] = Self::META_CODE.into();
292        Ok(())
293    }
294}