1pub 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#[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#[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 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}
198pub 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}