1414
1515//! HCI
1616
17- use std:: fmt;
1817// re-export here, and internal usages of these imports should refer to this mod, not the internal
1918// mod
2019pub ( crate ) use crate :: internal:: hci:: WithPacketType ;
21- pub use crate :: internal:: hci:: { packets, Error , Packet } ;
20+ pub use crate :: internal:: hci:: { packets, Address , Error , InvalidAddressHex , Packet } ;
2221
2322use crate :: wrapper:: core:: { TryFromPy , TryToPy } ;
2423use crate :: wrapper:: hci:: packets:: { AddressType , Command , ErrorCode } ;
25- use itertools:: Itertools as _;
2624use pyo3:: types:: PyBytes ;
2725use pyo3:: {
2826 exceptions:: PyException , intern, types:: PyModule , FromPyObject , IntoPy , PyAny , PyErr , PyObject ,
@@ -72,111 +70,11 @@ impl IntoPy<PyObject> for HciCommand {
7270 }
7371}
7472
75- /// A Bluetooth address
76- #[ derive( Clone , Copy , PartialEq , Eq , Hash ) ]
77- pub struct Address {
78- /// Little-endian bytes
79- le_bytes : [ u8 ; 6 ] ,
80- address_type : AddressType ,
81- }
82-
83- impl Address {
84- /// Creates a new address with the provided little-endian bytes.
85- pub fn from_le_bytes ( le_bytes : [ u8 ; 6 ] , address_type : AddressType ) -> Self {
86- Self {
87- le_bytes,
88- address_type,
89- }
90- }
91-
92- /// Creates a new address with the provided big endian hex (with or without `:` separators).
93- ///
94- /// # Examples
95- ///
96- /// ```
97- /// use bumble::{wrapper::{hci::{Address, packets::AddressType}}};
98- /// let hex = "F0:F1:F2:F3:F4:F5";
99- /// assert_eq!(
100- /// hex,
101- /// Address::from_be_hex(hex, AddressType::PublicDeviceAddress).unwrap().as_be_hex()
102- /// );
103- /// ```
104- pub fn from_be_hex (
105- address : & str ,
106- address_type : AddressType ,
107- ) -> Result < Self , InvalidAddressHex > {
108- let filtered: String = address. chars ( ) . filter ( |c| * c != ':' ) . collect ( ) ;
109- let mut bytes: [ u8 ; 6 ] = hex:: decode ( filtered)
110- . map_err ( |_| InvalidAddressHex { address } ) ?
111- . try_into ( )
112- . map_err ( |_| InvalidAddressHex { address } ) ?;
113- bytes. reverse ( ) ;
114-
115- Ok ( Self {
116- le_bytes : bytes,
117- address_type,
118- } )
119- }
120-
121- /// The type of address
122- pub fn address_type ( & self ) -> AddressType {
123- self . address_type
124- }
125-
126- /// True if the address is static
127- pub fn is_static ( & self ) -> bool {
128- !self . is_public ( ) && self . le_bytes [ 5 ] >> 6 == 3
129- }
130-
131- /// True if the address type is [AddressType::PublicIdentityAddress] or
132- /// [AddressType::PublicDeviceAddress]
133- pub fn is_public ( & self ) -> bool {
134- matches ! (
135- self . address_type,
136- AddressType :: PublicDeviceAddress | AddressType :: PublicIdentityAddress
137- )
138- }
139-
140- /// True if the address is resolvable
141- pub fn is_resolvable ( & self ) -> bool {
142- matches ! (
143- self . address_type,
144- AddressType :: PublicIdentityAddress | AddressType :: RandomIdentityAddress
145- )
146- }
147-
148- /// Address bytes in _little-endian_ format
149- pub fn as_le_bytes ( & self ) -> [ u8 ; 6 ] {
150- self . le_bytes
151- }
152-
153- /// Address bytes as big-endian colon-separated hex
154- pub fn as_be_hex ( & self ) -> String {
155- self . le_bytes
156- . into_iter ( )
157- . rev ( )
158- . map ( |byte| hex:: encode_upper ( [ byte] ) )
159- . join ( ":" )
160- }
161- }
162-
163- // show a more readable form than default Debug for a byte array
164- impl fmt:: Debug for Address {
165- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
166- write ! (
167- f,
168- "Address {{ address: {}, type: {:?} }}" ,
169- self . as_be_hex( ) ,
170- self . address_type
171- )
172- }
173- }
174-
17573impl TryToPy for Address {
17674 fn try_to_py < ' py > ( & self , py : Python < ' py > ) -> PyResult < & ' py PyAny > {
17775 PyModule :: import ( py, intern ! ( py, "bumble.device" ) ) ?
17876 . getattr ( intern ! ( py, "Address" ) ) ?
179- . call1 ( ( PyBytes :: new ( py, & self . le_bytes ) , self . address_type ) )
77+ . call1 ( ( PyBytes :: new ( py, & self . as_le_bytes ( ) ) , self . address_type ( ) ) )
18078 }
18179}
18280
@@ -194,20 +92,10 @@ impl TryFromPy for Address {
19492
19593 let address = obj. call_method0 ( intern ! ( py, "to_bytes" ) ) ?. extract ( ) ?;
19694
197- Ok ( Self {
198- le_bytes : address,
199- address_type,
200- } )
95+ Ok ( Self :: from_le_bytes ( address, address_type) )
20196 }
20297}
20398
204- /// Error type for [Address::from_be_hex].
205- #[ derive( Debug , thiserror:: Error ) ]
206- #[ error( "Invalid address hex: {address}" ) ]
207- pub struct InvalidAddressHex < ' a > {
208- address : & ' a str ,
209- }
210-
21199/// An error meaning that the internal u64 value used to convert to [packets::Address] did not
212100/// represent a valid BT address.
213101#[ derive( Debug , thiserror:: Error ) ]
0 commit comments