btmgmt_packet/
lib.rs

1#![doc(html_root_url = "https://docs.rs/btmgmt-packet/0.2.5")]
2#![allow(non_upper_case_globals)]
3//! Linux bluetooth mgmt API packet structures.
4//!
5//! see [bluez docs/mgmt-api.txt](https://git.kernel.org/pub/scm/bluetooth/bluez.git/plain/doc/mgmt-api.txt)
6//!
7//! ## License
8//!
9//! Licensed under either of
10//! * Apache License, Version 2.0
11//!   ([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>)
12//! * MIT license
13//!   ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)
14//! at your option.
15//!
16//! ## Contribution
17//!
18//! Unless you explicitly state otherwise, any contribution intentionally submitted
19//! for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
20//! dual licensed as above, without any additional terms or conditions.!
21
22use 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/// Controller Index
141#[derive(Debug, Clone, PartialEq, Eq, Hash)]
142pub enum ControllerIndex {
143    /// Controller index
144    ControllerId(u16),
145    /// Not related to any controller
146    NonController,
147}
148
149impl ControllerIndex {
150    /// true if [`Self::NonController`]
151    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) // FIXME reverse?
325    }
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]) // FIXME reverse?
331    }
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
613// ?
614impl<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
620// ?
621impl<L> TryFrom<VariableLengthBytes<L>> for u16 {
622    type Error = (); // FIXME
623    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),)* // FIXME
881                    _ => 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}