1#![doc(html_root_url = "https://docs.rs/btmgmt-packet/0.2.5")]
2#![allow(non_upper_case_globals)]
3use std::collections::HashSet;
23use std::convert::{TryFrom, TryInto};
24use std::ffi::{CString, NulError};
25use std::fmt;
26use std::io;
27use std::marker::PhantomData;
28use std::ops::{Deref, DerefMut};
29use std::str::FromStr;
30
31use bitflags::bitflags;
32use derive_builder::Builder;
33use derive_new::new as New;
34use getset::Getters;
35
36use btmgmt_packet_helper as helper;
37use helper::helper::{IterNewtype, Newtype};
38#[doc(hidden)]
39pub use helper::pack::{self, Pack, Unpack};
40
41pub mod command;
42pub mod event;
43
44#[derive(Debug, Clone, Newtype, New)]
45pub struct Address(bdaddr::Address);
46
47impl FromStr for Address {
48 type Err = <bdaddr::Address as FromStr>::Err;
49
50 fn from_str(s: &str) -> Result<Self, Self::Err> {
51 Ok(Self(FromStr::from_str(s)?))
52 }
53}
54
55impl Pack for Address {
56 fn pack<W>(&self, write: &mut W) -> pack::Result<()>
57 where
58 W: io::Write,
59 {
60 <[u8; 6]>::pack(&self.0.clone().into(), write)
61 }
62}
63
64impl Unpack for Address {
65 fn unpack<R>(read: &mut R) -> pack::Result<Self>
66 where
67 R: io::Read,
68 {
69 <[u8; 6]>::unpack(read).map(|a| Self(a.into()))
70 }
71}
72
73impl fmt::Display for Address {
74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75 self.0.fmt(f)
76 }
77}
78
79#[derive(Debug, Clone, PartialEq, Eq, Pack, Unpack)]
80#[pack(u8)]
81pub enum ErrorCode {
82 Success = 0x00,
83 UnknownCommand = 0x01,
84 NotConnected = 0x02,
85 Failed = 0x03,
86 ConnectFailed = 0x04,
87 AuthenticationFailed = 0x05,
88 NotPaired = 0x06,
89 NoResources = 0x07,
90 Timeout = 0x08,
91 AlreadyConnected = 0x09,
92 Busy = 0x0A,
93 Rejected = 0x0B,
94 NotSupported = 0x0C,
95 InvalidParameters = 0x0D,
96 Disconnected = 0x0E,
97 NotPowered = 0x0F,
98 Cancelled = 0x10,
99 InvalidIndex = 0x11,
100 RfKilled = 0x12,
101 AlreadyPaired = 0x13,
102 PermissionDenied = 0x14,
103}
104
105impl ErrorCode {
106 pub fn success(&self) -> bool {
107 self == &Self::Success
108 }
109}
110
111impl fmt::Display for ErrorCode {
112 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113 let m = match self {
114 Self::Success => "Success (0x00)",
115 Self::UnknownCommand => "Unknown Command (0x01)",
116 Self::NotConnected => "Not Connected (0x02)",
117 Self::Failed => "Failed (0x03)",
118 Self::ConnectFailed => "Connect Failed (0x04)",
119 Self::AuthenticationFailed => "Authentication Failed (0x05)",
120 Self::NotPaired => "Not Paired (0x06)",
121 Self::NoResources => "No Resources (0x07)",
122 Self::Timeout => "Timeout (0x08)",
123 Self::AlreadyConnected => "Already Connected (0x09)",
124 Self::Busy => "Busy (0x0A)",
125 Self::Rejected => "Rejected (0x0B)",
126 Self::NotSupported => "Not Supported (0x0C)",
127 Self::InvalidParameters => "Invalid Parameters (0x0D)",
128 Self::Disconnected => "Disconnected (0x0E)",
129 Self::NotPowered => "Not Powered (0x0F)",
130 Self::Cancelled => "Cancelled (0x10)",
131 Self::InvalidIndex => "Invalid Index (0x11)",
132 Self::RfKilled => "RFKilled (0x12)",
133 Self::AlreadyPaired => "Already Paired (0x13)",
134 Self::PermissionDenied => "Permission Denied (0x14)",
135 };
136 write!(f, "{}", m)
137 }
138}
139
140#[derive(Debug, Clone, PartialEq, Eq, Hash)]
142pub enum ControllerIndex {
143 ControllerId(u16),
145 NonController,
147}
148
149impl ControllerIndex {
150 pub fn is_non(&self) -> bool {
152 self == &Self::NonController
153 }
154}
155
156impl From<u16> for ControllerIndex {
157 fn from(v: u16) -> Self {
158 if v == 0xFFFF {
159 Self::NonController
160 } else {
161 Self::ControllerId(v)
162 }
163 }
164}
165
166impl From<Option<u16>> for ControllerIndex {
167 fn from(v: Option<u16>) -> Self {
168 match v {
169 Some(v) if v != 0xFFFF => ControllerIndex::ControllerId(v),
170 _ => ControllerIndex::NonController,
171 }
172 }
173}
174
175impl From<ControllerIndex> for u16 {
176 fn from(v: ControllerIndex) -> Self {
177 match v {
178 ControllerIndex::ControllerId(v) => v,
179 ControllerIndex::NonController => 0xFFFF,
180 }
181 }
182}
183
184impl Pack for ControllerIndex {
185 fn pack<W>(&self, write: &mut W) -> pack::Result<()>
186 where
187 W: io::Write,
188 {
189 u16::from(self.clone()).pack(write)?;
190 Ok(())
191 }
192}
193
194impl Unpack for ControllerIndex {
195 fn unpack<R>(read: &mut R) -> pack::Result<Self>
196 where
197 R: io::Read,
198 {
199 u16::unpack(read).map(Into::into)
200 }
201}
202
203#[derive(Debug, Getters)]
204#[getset(get = "pub")]
205pub struct CommandsEvents {
206 commands: Vec<command::CommandCode>,
207 events: Vec<event::EventCode>,
208}
209
210impl Pack for CommandsEvents {
211 fn pack<W>(&self, write: &mut W) -> pack::Result<()>
212 where
213 W: io::Write,
214 {
215 (self.commands.len() as u16).pack(write)?;
216 (self.events.len() as u16).pack(write)?;
217 for item in &self.commands {
218 item.pack(write)?;
219 }
220 for item in &self.events {
221 item.pack(write)?;
222 }
223 Ok(())
224 }
225}
226
227impl Unpack for CommandsEvents {
228 fn unpack<R>(read: &mut R) -> pack::Result<Self>
229 where
230 R: io::Read,
231 {
232 let num_commands = u16::unpack(read)?;
233 let num_events = u16::unpack(read)?;
234 let commands = (0..num_commands)
235 .map(|_| Unpack::unpack(read))
236 .collect::<Result<_, _>>()?;
237 let events = (0..num_events)
238 .map(|_| Unpack::unpack(read))
239 .collect::<Result<_, _>>()?;
240 Ok(Self { commands, events })
241 }
242}
243
244#[derive(Debug, Clone, PartialEq, Eq, Hash, Pack, Unpack)]
245#[pack(u8)]
246pub enum AddressType {
247 BrEdr = 0,
248 LePublic = 1,
249 LeRandom = 2,
250}
251
252#[derive(Debug, Clone, PartialEq, Eq, Default, IterNewtype)]
253#[iter_newtype(item = AddressType, into_iter = ::std::collections::hash_set::IntoIter<AddressType>, no_iter_mut)]
254pub struct AddressTypes(HashSet<AddressType>);
255
256impl Pack for AddressTypes {
257 fn pack<W>(&self, write: &mut W) -> pack::Result<()>
258 where
259 W: io::Write,
260 {
261 let mut v = 0u8;
262 for item in &self.0 {
263 v |= match item {
264 AddressType::BrEdr => 1 << 0,
265 AddressType::LePublic => 1 << 1,
266 AddressType::LeRandom => 1 << 2,
267 };
268 }
269 v.pack(write)
270 }
271}
272
273impl Unpack for AddressTypes {
274 fn unpack<R>(read: &mut R) -> pack::Result<Self>
275 where
276 R: io::Read,
277 {
278 let v = u8::unpack(read)?;
279 let mut r = HashSet::new();
280
281 if v & 1 << 0 != 0 {
282 r.insert(AddressType::BrEdr);
283 }
284 if v & 1 << 1 != 0 {
285 r.insert(AddressType::LePublic);
286 }
287 if v & 1 << 2 != 0 {
288 r.insert(AddressType::LeRandom);
289 }
290
291 Ok(Self(r))
292 }
293}
294
295bitflags! {
296 #[derive(Pack, Unpack)]
297 pub struct Settings: u32 {
298 const Powered = 1 << 0;
299 const Connectable = 1 << 1;
300 const FastConnectable = 1 << 2;
301 const Discoverable = 1 << 3;
302 const Bondable = 1 << 4;
303 const LinkLevelSecurity = 1 << 5;
304 const SecureSimplePairing = 1 << 6;
305 const BasicRateEnhancedDataRate = 1 << 7;
306 const HighSpeed = 1 << 8;
307 const LowEnergy = 1 << 9;
308 const Advertising = 1 << 10;
309 const SecureConnections = 1 << 11;
310 const DebugKeys = 1 << 12;
311 const Privacy = 1 << 13;
312 const ControllerConfiguration = 1 << 14;
313 const StaticAddress = 1 << 15;
314 const PhyConfiguration = 1 << 16;
315 const WidebandSpeech = 1 << 17;
316 }
317}
318
319#[derive(Debug, Clone, Pack, Unpack)]
320pub struct ClassOfDevice([u8; 3]);
321
322impl From<[u8; 3]> for ClassOfDevice {
323 fn from(v: [u8; 3]) -> Self {
324 Self(v) }
326}
327
328impl fmt::Display for ClassOfDevice {
329 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
330 write!(f, "{:02X}{:02X}{:02X}", self.0[0], self.0[1], self.0[2]) }
332}
333
334#[derive(Debug, thiserror::Error)]
335#[error("length too long {0:} < {1:}")]
336pub struct LengthTooLong(usize, usize);
337
338#[derive(Debug, thiserror::Error)]
339pub enum NameError {
340 #[error(transparent)]
341 LengthTooLong(#[from] LengthTooLong),
342
343 #[error(transparent)]
344 NulError(#[from] NulError),
345}
346
347#[derive(Clone, Pack, Unpack)]
348pub struct FixedLengthName<const N: usize>(Box<[u8; N]>);
349
350impl<const N: usize> FixedLengthName<N> {
351 pub fn new<T: Into<Vec<u8>>>(t: T) -> Result<Self, NameError> {
352 let s = CString::new(t)?;
353 let b = s.as_bytes_with_nul();
354 if b.len() > N {
355 return Err(LengthTooLong(N, b.len()).into());
356 }
357
358 let mut v = [0; N];
359 (&mut v[..b.len()]).copy_from_slice(b);
360 Ok(Self(Box::new(v)))
361 }
362
363 pub fn to_string_lossy(&self) -> String {
364 let b = self.0.split(|b| b == &0).next().unwrap_or(b"");
365 CString::new(b).unwrap().to_string_lossy().to_string()
366 }
367}
368
369impl<const N: usize> fmt::Debug for FixedLengthName<N> {
370 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
371 let b = self.0.split(|b| b == &0).next().unwrap_or(b"");
372 CString::new(b).unwrap().fmt(f)
373 }
374}
375
376impl<const N: usize> FromStr for FixedLengthName<N> {
377 type Err = NameError;
378 fn from_str(s: &str) -> Result<Self, Self::Err> {
379 Self::new(s)
380 }
381}
382
383pub type Name = FixedLengthName<249>;
384pub type ShortName = FixedLengthName<11>;
385
386#[derive(Debug, Pack, Unpack)]
387#[pack(u8)]
388pub enum Discoverable {
389 Disable = 0x00,
390 General = 0x01,
391 Limited = 0x02,
392}
393
394#[derive(Debug, Clone, Default, Newtype, New)]
395pub struct Uuid(uuid::Uuid);
396
397impl Pack for Uuid {
398 fn pack<W>(&self, read: &mut W) -> pack::Result<()>
399 where
400 W: io::Write,
401 {
402 self.0.to_u128_le().pack(read)?;
403 Ok(())
404 }
405}
406
407impl Unpack for Uuid {
408 fn unpack<R>(read: &mut R) -> pack::Result<Self>
409 where
410 R: io::Read,
411 {
412 Ok(Self(uuid::Uuid::from_u128_le(Unpack::unpack(read)?)))
413 }
414}
415
416impl FromStr for Uuid {
417 type Err = <uuid::Uuid as FromStr>::Err;
418
419 fn from_str(s: &str) -> Result<Self, Self::Err> {
420 Ok(Self(FromStr::from_str(s)?))
421 }
422}
423
424#[derive(Debug, Clone, Pack, Unpack)]
425#[pack(u8)]
426pub enum LinkKeyType {
427 Combinationkey = 0x00,
428 LocalUnitkey = 0x01,
429 RemoteUnitkey = 0x02,
430 DebugCombinationkey = 0x03,
431 UnauthenticatedCombinationkeyfromP192 = 0x04,
432 AuthenticatedCombinationkeyfromP192 = 0x05,
433 ChangedCombinationkey = 0x06,
434 UnauthenticatedCombinationkeyfromP256 = 0x07,
435 AuthenticatedCombinationkeyfromP256 = 0x08,
436}
437
438#[derive(Debug, Clone, Pack, Unpack, Getters, New)]
439#[getset(get = "pub")]
440pub struct LinkKey {
441 address: Address,
442 address_type: AddressType,
443 key_type: LinkKeyType,
444 value: [u8; 16],
445 pin_length: u8,
446}
447
448#[derive(Debug, Clone, Pack, Unpack)]
449#[pack(u8)]
450pub enum LongTermKeyType {
451 UnauthenticatedKey = 0x00,
452 AuthenticatedKey = 0x01,
453 UnauthenticatedP256Key = 0x02,
454 AuthenticatedP256Key = 0x03,
455 DebugKeyP256 = 0x04,
456}
457
458#[derive(Debug, Clone, Pack, Unpack, Getters, Builder)]
459#[getset(get = "pub")]
460pub struct LongTermKey {
461 address: Address,
462 address_type: AddressType,
463 key_type: LongTermKeyType,
464 master: bool,
465 encryption_size: u8,
466 encryption_diversifier: u16,
467 random_number: [u8; 8],
468 value: [u8; 16],
469}
470
471#[derive(Debug, Clone, Pack, Unpack, Getters, New)]
472#[getset(get = "pub")]
473pub struct IdentityResolvingKey {
474 address: Address,
475 address_type: AddressType,
476 value: [u8; 16],
477}
478
479#[derive(Debug, Pack, Unpack)]
480#[pack(u8)]
481pub enum IoCapability {
482 DisplayOnly = 0,
483 DisplayYesNo = 1,
484 KeyboardOnly = 2,
485 NoInputNoOutput = 3,
486 KeyboardDisplay = 4,
487}
488
489#[derive(Debug, Pack, Unpack)]
490#[pack(u16)]
491pub enum DeviceIdSource {
492 DisableDeviceId = 0x0000,
493 BluetoothSig = 0x0001,
494 UsbImplementersForum = 0x0002,
495}
496
497#[derive(Debug, Pack, Unpack)]
498#[pack(u8)]
499pub enum Advertising {
500 Disable = 0x00,
501 Enable = 0x01,
502 Connectable = 0x02,
503}
504
505#[derive(Debug, Pack, Unpack)]
506#[pack(u8)]
507pub enum SecureConnections {
508 Disable = 0x00,
509 Enable = 0x01,
510 Only = 0x02,
511}
512
513#[derive(Debug, Pack, Unpack)]
514#[pack(u8)]
515pub enum DebugKeys {
516 Disable = 0x00,
517 Enable = 0x01,
518 ForEach = 0x02,
519}
520
521#[derive(Debug, Pack, Unpack)]
522#[pack(u8)]
523pub enum Privacy {
524 Disable = 0x00,
525 Enable = 0x01,
526 Limited = 0x02,
527}
528
529#[derive(Debug, Clone, Pack, Unpack)]
530#[pack(u8)]
531pub enum Action {
532 Background = 0,
533 Allow = 1,
534 AutoConnect = 2,
535}
536
537#[derive(Debug, Pack, Unpack, New, Getters)]
538#[getset(get = "pub")]
539pub struct ConnectionParameter {
540 address: Address,
541 address_type: AddressType,
542 min_connection_interval: u16,
543 max_connection_interval: u16,
544 connection_latency: u16,
545 supervision_timeout: u16,
546}
547
548bitflags! {
549 #[derive(Pack, Unpack)]
550 pub struct ControllerConfigurationOption: u32 {
551 const ExternalConfiguration = 1 << 0;
552 const BluetoothPublicAddressConfiguration = 1 << 1;
553 }
554}
555
556#[derive(Debug, Clone)]
557pub struct VariableLengthBytes<L = u16>(Box<[u8]>, PhantomData<L>);
558
559impl Pack for VariableLengthBytes<u16> {
560 fn pack<W>(&self, write: &mut W) -> pack::Result<()>
561 where
562 W: io::Write,
563 {
564 (self.0.len() as u16).pack(write)?;
565 self.0.pack(write)?;
566 Ok(())
567 }
568}
569
570impl Unpack for VariableLengthBytes<u16> {
571 fn unpack<R>(read: &mut R) -> pack::Result<Self>
572 where
573 R: io::Read,
574 {
575 let len = u16::unpack(read)? as usize;
576 let mut read = <&mut R as io::Read>::take(read, len as u64);
577 let buf = <Box<[u8]>>::unpack(&mut read)?;
578 if buf.len() != len {
579 return Err(io::Error::new(io::ErrorKind::Other, "few bytes.").into());
580 }
581
582 Ok(Self(buf, PhantomData))
583 }
584}
585
586impl Pack for VariableLengthBytes<u8> {
587 fn pack<W>(&self, write: &mut W) -> pack::Result<()>
588 where
589 W: io::Write,
590 {
591 (self.0.len() as u8).pack(write)?;
592 self.0.pack(write)?;
593 Ok(())
594 }
595}
596
597impl Unpack for VariableLengthBytes<u8> {
598 fn unpack<R>(read: &mut R) -> pack::Result<Self>
599 where
600 R: io::Read,
601 {
602 let len = u8::unpack(read)? as usize;
603 let mut read = <&mut R as io::Read>::take(read, len as u64);
604 let buf = <Box<[u8]>>::unpack(&mut read)?;
605 if buf.len() != len {
606 return Err(io::Error::new(io::ErrorKind::Other, "few bytes.").into());
607 }
608
609 Ok(Self(buf, PhantomData))
610 }
611}
612
613impl<L> From<u16> for VariableLengthBytes<L> {
615 fn from(v: u16) -> Self {
616 Self(v.to_le_bytes().to_vec().into(), PhantomData)
617 }
618}
619
620impl<L> TryFrom<VariableLengthBytes<L>> for u16 {
622 type Error = (); fn try_from(value: VariableLengthBytes<L>) -> Result<Self, Self::Error> {
624 match *value.0.as_ref() {
625 [i1, i2] => Ok(u16::from_le_bytes([i1, i2])),
626 _ => Err(()),
627 }
628 }
629}
630
631impl<L> AsRef<[u8]> for VariableLengthBytes<L> {
632 fn as_ref(&self) -> &[u8] {
633 &self.0
634 }
635}
636
637impl<L> AsMut<[u8]> for VariableLengthBytes<L> {
638 fn as_mut(&mut self) -> &mut [u8] {
639 &mut self.0
640 }
641}
642
643impl<L> Deref for VariableLengthBytes<L> {
644 type Target = [u8];
645
646 fn deref(&self) -> &Self::Target {
647 &self.0
648 }
649}
650
651impl<L> DerefMut for VariableLengthBytes<L> {
652 fn deref_mut(&mut self) -> &mut Self::Target {
653 &mut self.0
654 }
655}
656
657#[derive(Debug, Clone, Pack, Unpack)]
658#[pack(u8)]
659pub enum ControllerType {
660 PrimaryController = 0x00,
661 UnconfiguredController = 0x01,
662 AlternateMacPhyController = 0x02,
663}
664
665#[derive(Debug, Clone, Pack, Unpack)]
666#[pack(u8)]
667pub enum ControllerBus {
668 Virtual = 0x00,
669 Usb = 0x01,
670 Pcmcia = 0x02,
671 Uart = 0x03,
672 Rs232 = 0x04,
673 Pci = 0x05,
674 Sdio = 0x06,
675 Spi = 0x07,
676 I2c = 0x08,
677 Smd = 0x09,
678 Virtio = 0x0A,
679}
680
681bitflags! {
682 #[derive(Pack, Unpack)]
683 pub struct AdvertisingFlag: u32 {
684 const SwitchIntoConnectableMode = 1 << 0;
685 const AdvertiseAsDiscoverable = 1 << 1;
686 const AdvertiseAsLimitedDiscoverable = 1 << 2;
687 const AddFlagsFieldToAdvData = 1 << 3;
688 const AddTxPowerFieldToAdvData = 1 << 4;
689 const AddAppearanceFieldToScanResp = 1 << 5;
690 const AddLocalNameInScanResp = 1 << 6;
691 const SecondaryChannelWithLe1M = 1 << 7;
692 const SecondaryChannelWithLe2M = 1 << 8;
693 const SecondaryChannelWithLeCoded = 1 << 9;
694 }
695}
696
697#[derive(Debug, Clone, Pack, Unpack, Newtype, New)]
698pub struct AdvertiseInstance(u8);
699
700#[derive(Debug, IterNewtype)]
701pub struct AdvertiseInstances(Vec<AdvertiseInstance>);
702
703impl Pack for AdvertiseInstances {
704 fn pack<W>(&self, write: &mut W) -> pack::Result<()>
705 where
706 W: io::Write,
707 {
708 (self.0.len() as u8).pack(write)?;
709 for item in &self.0 {
710 item.pack(write)?;
711 }
712 Ok(())
713 }
714}
715
716impl Unpack for AdvertiseInstances {
717 fn unpack<R>(read: &mut R) -> pack::Result<Self>
718 where
719 R: io::Read,
720 {
721 let len = u8::unpack(read)? as usize;
722 let v = (0..len)
723 .map(|_| Unpack::unpack(read))
724 .collect::<Result<Vec<_>, _>>()?;
725 Ok(Self(v))
726 }
727}
728
729impl<'a> std::iter::IntoIterator for &'a AdvertiseInstances {
730 type Item = &'a AdvertiseInstance;
731 type IntoIter = std::slice::Iter<'a, AdvertiseInstance>;
732 fn into_iter(self) -> Self::IntoIter {
733 (&self.0).iter()
734 }
735}
736
737#[derive(Debug)]
738pub struct AdvDataScanResp(Box<[u8]>, Box<[u8]>);
739
740impl AdvDataScanResp {
741 pub fn new<A, S>(advdata: A, scanresp: S) -> Self
742 where
743 A: AsRef<[u8]>,
744 S: AsRef<[u8]>,
745 {
746 let advdata = advdata.as_ref();
747 let scanresp = scanresp.as_ref();
748 Self(advdata.into(), scanresp.into())
749 }
750}
751
752impl Pack for AdvDataScanResp {
753 fn pack<W>(&self, write: &mut W) -> pack::Result<()>
754 where
755 W: io::Write,
756 {
757 (self.0.len() as u8).pack(write)?;
758 (self.1.len() as u8).pack(write)?;
759 self.0.pack(write)?;
760 self.1.pack(write)?;
761 Ok(())
762 }
763}
764
765impl Unpack for AdvDataScanResp {
766 fn unpack<R>(read: &mut R) -> pack::Result<Self>
767 where
768 R: io::Read,
769 {
770 let adv_data_len = u8::unpack(read)? as usize;
771 let scan_resp_len = u8::unpack(read)? as usize;
772
773 let mut read = <&mut R as io::Read>::take(read, adv_data_len as u64);
774 let adv_data = <Box<[u8]>>::unpack(&mut read)?;
775 let read = read.into_inner();
776 if adv_data.len() != adv_data_len {
777 return Err(io::Error::new(io::ErrorKind::Other, "unexpected length.").into());
778 }
779
780 let mut read = <&mut R as io::Read>::take(read, adv_data_len as u64);
781 let scan_resp = <Box<[u8]>>::unpack(&mut read)?;
782 if scan_resp.len() != scan_resp_len {
783 return Err(io::Error::new(io::ErrorKind::Other, "unexpected length.").into());
784 }
785
786 Ok(Self(adv_data, scan_resp))
787 }
788}
789
790impl<A, B> From<(A, B)> for AdvDataScanResp
791where
792 A: Into<Box<[u8]>>,
793 B: Into<Box<[u8]>>,
794{
795 fn from((a, b): (A, B)) -> Self {
796 Self(a.into(), b.into())
797 }
798}
799
800bitflags! {
801 #[derive(Pack, Unpack)]
802 pub struct Phys: u32 {
803 const Br1M1Slot = 1 << 0;
804 const Br1M3Slot = 1 << 1;
805 const Br1M5Slot = 1 << 2;
806 const Edr2M1Slot = 1 << 3;
807 const Edr2M3Slot = 1 << 4;
808 const Edr2M5Slot = 1 << 5;
809 const Edr3M1Slot = 1 << 6;
810 const Edr3M3Slot = 1 << 7;
811 const Edr3M5Slot = 1 << 8;
812 const Le1MTx = 1 << 9;
813 const Le1MRx = 1 << 10;
814 const Le2MTx = 1 << 11;
815 const Le2MRx = 1 << 12;
816 const LeCodedTx = 1 << 13;
817 const LeCodedRx = 1 << 14;
818 }
819}
820
821#[derive(Debug, Pack, Unpack)]
822#[pack(u8)]
823pub enum BlockedKeyType {
824 LinkKey = 0x00,
825 LongTermKey = 0x01,
826 IdentityResolvingKey = 0x02,
827}
828
829#[derive(Debug, Pack, Unpack, New, Getters)]
830#[getset(get = "pub")]
831pub struct BlockedKey {
832 key_type: BlockedKeyType,
833 value: [u8; 16],
834}
835
836bitflags! {
837 #[derive(Pack, Unpack)]
838 pub struct FeatureFlags: u32 {
839 const FeatureActive = 1 << 0;
840 const CauseChangeInSupportedSettings = 1 << 1;
841 }
842}
843
844#[derive(Debug, Pack, Unpack)]
845#[pack(u8)]
846pub enum FeatureAction {
847 Disable = 0x00,
848 Enable = 0x01,
849}
850
851macro_rules! configuration_parameter {
852 (
853 $(#[$attrs:meta])*
854 $vis:vis enum $name:ident: $typename:ident {
855 $( $vname:ident($vty:ty) => $vcode:literal, )*
856 }
857 ) => {
858 $(#[$attrs])*
859 $vis enum $name {
860 $( $vname($vty), )*
861 }
862
863 #[derive(Debug, Clone)]
864 $vis enum $typename {
865 $( $vname, )*
866 }
867
868 impl $name {
869 #[allow(unreachable_patterns)]
870 pub fn for_type(&self) -> $typename {
871 match self {
872 $( Self::$vname(..) => $typename::$vname,)*
873 _ => unreachable!(),
874 }
875 }
876
877 #[allow(unreachable_patterns)]
878 pub fn value_as_u16(&self) -> Option<u16> {
879 match self {
880 $( Self::$vname(v) => Some(*v),)* _ => unreachable!(),
882 }
883 }
884 }
885
886 impl Pack for $name {
887 #[allow(unreachable_code, unused_variables, unreachable_patterns)]
888 fn pack<W>(&self, write: &mut W) -> pack::Result<()> where W: io::Write {
889 let (t, v) = match self {
890 $(Self::$vname(v) => ($vcode, VariableLengthBytes::from(*v)),)*
891 _ => unreachable!(),
892 };
893 <u16 as Pack>::pack(&t, write)?;
894 <VariableLengthBytes<u8> as Pack>::pack(&v, write)?;
895 Ok(())
896 }
897 }
898
899 impl Unpack for $name {
900 #[allow(unreachable_code, unused_variables)]
901 fn unpack<R>(read: &mut R) -> pack::Result<Self> where R: io::Read {
902 let t = u16::unpack(read)?;
903 let v = VariableLengthBytes::<u8>::unpack(read)?;
904 Ok(match t {
905 $($vcode => Self::$vname(v.try_into().map_err(|_| pack::Error::Io(io::Error::new(io::ErrorKind::Other, "unexpected data")))?),)*
906 t => return Err(io::Error::new(io::ErrorKind::Other, format!("unknown type {}", t)).into()),
907 })
908 }
909 }
910 }
911}
912
913configuration_parameter! {
914 #[derive(Debug, Clone)]
915 pub enum SystemConfigurationParameter: SystemConfigurationParameterType {
916 BrEdrPageScanType(u16) => 0x0000,
917 BrEdrPageScanInterval(u16) => 0x0001,
918 BrEdrPageScanWindow(u16) => 0x0002,
919 BrEdrInquiryScanType(u16) => 0x0003,
920 BrEdrInquiryScanInterval(u16) => 0x0004,
921 BrEdrInquiryScanWindow(u16) => 0x0005,
922 BrEdrLinkSupervisionTimeout(u16) => 0x0006,
923 BrEdrPageTimeout(u16) => 0x0007,
924 BrEdrMinSniffInterval(u16) => 0x0008,
925 BrEdrMaxSniffInterval(u16) => 0x0009,
926 LEAdvertisementMinInterval(u16) => 0x000a,
927 LEAdvertisementMaxInterval(u16) => 0x000b,
928 LEMultiAdvertisementRotationInterval(u16) => 0x000c,
929 LEScanningIntervalforautoconnect(u16) => 0x000d,
930 LEScanningWindowforautoconnect(u16) => 0x000e,
931 LEScanningIntervalforwakescenarios(u16) => 0x000f,
932 LEScanningWindowforwakescenarios(u16) => 0x0010,
933 LEScanningIntervalfordiscovery(u16) => 0x0011,
934 LEScanningWindowfordiscovery(u16) => 0x0012,
935 LEScanningIntervalforadvmonitoring(u16) => 0x0013,
936 LEScanningWindowforadvmonitoring(u16) => 0x0014,
937 LEScanningIntervalforconnect(u16) => 0x0015,
938 LEScanningWindowforconnect(u16) => 0x0016,
939 LEMinConnectionInterval(u16) => 0x0017,
940 LEMaxConnectionInterval(u16) => 0x0018,
941 LEConnectionLatency(u16) => 0x0019,
942 LEConnectionSupervisionTimeout(u16) => 0x001a,
943 LEAutoconnectTimeout(u16) => 0x001b,
944 }
945}
946
947configuration_parameter! {
948 #[derive(Debug, Clone)]
949 pub enum RuntimeConfigurationParameter: RuntimeConfigurationParameterType {
950 }
951}
952
953#[derive(Debug, Clone, IterNewtype)]
954pub struct Remaining<T>(Vec<T>);
955
956impl<T> Pack for Remaining<T>
957where
958 T: Pack,
959{
960 fn pack<W>(&self, write: &mut W) -> pack::Result<()>
961 where
962 W: io::Write,
963 {
964 for item in &self.0 {
965 item.pack(write)?;
966 }
967 Ok(())
968 }
969}
970
971impl<T> Unpack for Remaining<T>
972where
973 T: Unpack,
974{
975 fn unpack<R>(read: &mut R) -> pack::Result<Self>
976 where
977 R: io::Read,
978 {
979 let mut v = vec![];
980 loop {
981 match Unpack::unpack(read) {
982 Ok(item) => v.push(item),
983 Err(pack::Error::NoDataAvailable) => return Ok(Self(v)),
984 Err(err) => return Err(err),
985 }
986 }
987 }
988}
989
990bitflags! {
991 #[derive(Pack, Unpack)]
992 pub struct DeviceFlags: u32 {
993 const RemoteWakeupEnabled = 1 << 0;
994 }
995}
996
997bitflags! {
998 #[derive(Pack, Unpack)]
999 pub struct AdvertisementMonitorFeatures: u32 {
1000 const AdvertisementContentMonitoringBasedOnPatternsWithLogicalOr = 1 << 0;
1001 }
1002}
1003
1004#[derive(Debug, Clone, Pack, Unpack, Newtype, New)]
1005pub struct AdvertisementMonitorHandle(u16);
1006
1007#[derive(Debug, Pack, Unpack, Getters)]
1008#[getset(get = "pub")]
1009pub struct AdvertisementPattern {
1010 ad_type: u8,
1011 offset: u8,
1012 length: u8,
1013 value: [u8; 31],
1014}
1015
1016impl AdvertisementPattern {
1017 pub fn new<V>(ad_type: u8, offset: u8, value: V) -> Self
1018 where
1019 V: AsRef<[u8]>,
1020 {
1021 let v = value.as_ref();
1022 let length = v.len() as u8;
1023
1024 let mut value = [0; 31];
1025 value[0..v.len()].copy_from_slice(v);
1026 Self {
1027 ad_type,
1028 offset,
1029 length,
1030 value,
1031 }
1032 }
1033}
1034
1035bitflags! {
1036 #[derive(Pack, Unpack)]
1037 pub struct DeviceConnectFlags: u32 {
1038 const ConfirmName = 1 << 0;
1039 const LegacyPairing = 1 << 1;
1040 const NotConnectable = 1 << 2;
1041 }
1042}
1043
1044#[derive(Debug, Clone, Pack, Unpack)]
1045#[pack(u8)]
1046pub enum DeviceDisconnectReason {
1047 Unspecified = 0,
1048 ConnectionTimeout = 1,
1049 ConnectionTerminatedByLocalHost = 2,
1050 ConnectionTerminatedByRemoteHost = 3,
1051 ConnectionTerminatedDueToAuthenticationFailure = 4,
1052 ConnectionTerminatedByLocalHostForSuspend = 5,
1053}
1054
1055#[derive(Debug, Clone, Pack, Unpack)]
1056#[pack(u8)]
1057pub enum ConfirmHint {
1058 Full = 0,
1059 Simple = 1,
1060}
1061
1062#[derive(Debug, Clone, Pack, Unpack)]
1063#[pack(u8)]
1064pub enum SignatureResolvingKeyType {
1065 UnauthenticatedLocalCsrk = 0x00,
1066 UnauthenticatedRemoteCsrk = 0x01,
1067 AuthenticatedLocalCsrk = 0x02,
1068 AuthenticatedRemoteCsrk = 0x03,
1069}
1070
1071#[derive(Debug, Clone, Pack, Unpack, New, Getters)]
1072#[getset(get = "pub")]
1073pub struct SignatureResolvingKey {
1074 address: Address,
1075 address_type: AddressType,
1076 typ: SignatureResolvingKeyType,
1077 value: [u8; 16],
1078}
1079
1080#[derive(Debug, Clone, Pack, Unpack)]
1081#[pack(u8)]
1082pub enum SuspendState {
1083 Running = 0,
1084 DisconnectedAndNotScanning = 1,
1085 PageScanAndOrPassiveScanning = 2,
1086}
1087
1088#[derive(Debug, Clone, Pack, Unpack)]
1089#[pack(u8)]
1090pub enum WakeReason {
1091 ResumeFromNonBluetoothWakeSource = 0,
1092 WakeDueToUnexpectedEvent = 1,
1093 RemoteWakeDueToPeerDeviceConnection = 2,
1094}