simplersble/
lib.rs

1pub mod types;
2pub mod adapter;
3pub mod peripheral;
4pub mod service;
5pub mod characteristic;
6pub mod descriptor;
7
8use adapter::InnerAdapter;
9use peripheral::InnerPeripheral;
10
11pub use types::{Error, BluetoothAddressType, CharacteristicCapability};
12pub use adapter::Adapter;
13pub use adapter::ScanEvent;
14pub use peripheral::Peripheral;
15pub use peripheral::ConnectionEvent;
16pub use peripheral::ValueChangedEvent;
17pub use service::Service;
18pub use characteristic::Characteristic;
19pub use descriptor::Descriptor;
20
21#[cxx::bridge]
22mod ffi {
23
24    // ----------------------------------------------------------------------------------
25
26    // The following structs are used to wrap the underlying classes into the objects
27    // that are used in the Rust bindings.
28
29    #[namespace = "Bindings"]
30    struct RustyAdapterWrapper {
31        internal: UniquePtr<RustyAdapter>,
32    }
33
34    #[namespace = "Bindings"]
35    struct RustyPeripheralWrapper {
36        internal: UniquePtr<RustyPeripheral>,
37    }
38
39    #[namespace = "Bindings"]
40    struct RustyServiceWrapper {
41        internal: UniquePtr<RustyService>,
42    }
43
44    #[namespace = "Bindings"]
45    struct RustyCharacteristicWrapper {
46        internal: UniquePtr<RustyCharacteristic>,
47    }
48
49    #[namespace = "Bindings"]
50    struct RustyDescriptorWrapper {
51        internal: UniquePtr<RustyDescriptor>,
52    }
53
54    // ----------------------------------------------------------------------------------
55
56    #[namespace = "Bindings"]
57    struct RustyManufacturerDataWrapper {
58        company_id: u16,
59        data: Vec<u8>,
60    }
61
62    #[namespace = "SimpleBLE"]
63    #[repr(i32)]
64    enum BluetoothAddressType {
65        PUBLIC,
66        RANDOM,
67        UNSPECIFIED,
68    }
69
70    // ----------------------------------------------------------------------------------
71
72    #[namespace = "SimpleRsBLE"]
73    extern "Rust" {
74        type InnerAdapter;
75
76        pub fn on_callback_scan_start(self: &mut InnerAdapter);
77        pub fn on_callback_scan_stop(self: &mut InnerAdapter);
78        pub fn on_callback_scan_updated(self: &mut InnerAdapter, peripheral: &mut RustyPeripheralWrapper);
79        pub fn on_callback_scan_found(self: &mut InnerAdapter, peripheral: &mut RustyPeripheralWrapper);
80
81        type InnerPeripheral;
82
83        pub fn on_callback_connected(self: &mut InnerPeripheral);
84        pub fn on_callback_disconnected(self: &mut InnerPeripheral);
85        pub fn on_callback_characteristic_updated(
86            self: &mut InnerPeripheral,
87            service: &String,
88            Characteristic: &String,
89            data: &Vec<u8>,
90        );
91    }
92
93    unsafe extern "C++" {
94        include!("src/bindings/Bindings.hpp");
95
96        #[namespace = "SimpleBLE"]
97        type BluetoothAddressType;
98
99        #[namespace = "Bindings"]
100        type RustyAdapter;
101
102        #[namespace = "Bindings"]
103        type RustyPeripheral;
104
105        #[namespace = "Bindings"]
106        type RustyService;
107
108        #[namespace = "Bindings"]
109        type RustyCharacteristic;
110
111        #[namespace = "Bindings"]
112        type RustyDescriptor;
113
114        // Common functions
115
116        #[namespace = "Bindings"]
117        fn RustyAdapter_bluetooth_enabled() -> Result<bool>;
118
119        #[namespace = "Bindings"]
120        fn RustyAdapter_get_adapters() -> Result<Vec<RustyAdapterWrapper>>;
121
122        // RustyAdapter functions
123
124        fn link(self: &RustyAdapter, target: Pin<&mut InnerAdapter>) -> Result<()>;
125        fn unlink(self: &RustyAdapter) -> Result<()>;
126
127        fn identifier(self: &RustyAdapter) -> Result<String>;
128        fn address(self: &RustyAdapter) -> Result<String>;
129
130        fn scan_start(self: &RustyAdapter) -> Result<()>;
131        fn scan_stop(self: &RustyAdapter) -> Result<()>;
132        fn scan_for(self: &RustyAdapter, timeout_ms: i32) -> Result<()>;
133        fn scan_is_active(self: &RustyAdapter) -> Result<bool>;
134        fn scan_get_results(self: &RustyAdapter) -> Result<Vec<RustyPeripheralWrapper>>;
135
136        fn get_paired_peripherals(self: &RustyAdapter) -> Result<Vec<RustyPeripheralWrapper>>;
137
138        // RustyPeripheral functions
139
140        fn link(self: &RustyPeripheral, target: Pin<&mut InnerPeripheral>) -> Result<()>;
141        fn unlink(self: &RustyPeripheral) -> Result<()>;
142
143        fn identifier(self: &RustyPeripheral) -> Result<String>;
144        fn address(self: &RustyPeripheral) -> Result<String>;
145        fn address_type(self: &RustyPeripheral) -> Result<BluetoothAddressType>;
146        fn rssi(self: &RustyPeripheral) -> Result<i16>;
147
148        fn tx_power(self: &RustyPeripheral) -> Result<i16>;
149        fn mtu(self: &RustyPeripheral) -> Result<u16>;
150
151        fn connect(self: &RustyPeripheral) -> Result<()>;
152        fn disconnect(self: &RustyPeripheral) -> Result<()>;
153        fn is_connected(self: &RustyPeripheral) -> Result<bool>;
154        fn is_connectable(self: &RustyPeripheral) -> Result<bool>;
155        fn is_paired(self: &RustyPeripheral) -> Result<bool>;
156        fn unpair(self: &RustyPeripheral) -> Result<()>;
157
158        fn services(self: &RustyPeripheral) -> Result<Vec<RustyServiceWrapper>>;
159        fn manufacturer_data(self: &RustyPeripheral) -> Result<Vec<RustyManufacturerDataWrapper>>;
160
161        fn read(
162            self: &RustyPeripheral,
163            service: &String,
164            characteristic: &String,
165        ) -> Result<Vec<u8>>;
166        fn write_request(
167            self: &RustyPeripheral,
168            service: &String,
169            characteristic: &String,
170            data: &Vec<u8>,
171        ) -> Result<()>;
172        fn write_command(
173            self: &RustyPeripheral,
174            service: &String,
175            characteristic: &String,
176            data: &Vec<u8>,
177        ) -> Result<()>;
178        fn notify(self: &RustyPeripheral, service: &String, characteristic: &String) -> Result<()>;
179        fn indicate(
180            self: &RustyPeripheral,
181            service: &String,
182            characteristic: &String,
183        ) -> Result<()>;
184        fn unsubscribe(
185            self: &RustyPeripheral,
186            service: &String,
187            characteristic: &String,
188        ) -> Result<()>;
189
190        fn read_descriptor(
191            self: &RustyPeripheral,
192            service: &String,
193            characteristic: &String,
194            descriptor: &String,
195        ) -> Result<Vec<u8>>;
196        fn write_descriptor(
197            self: &RustyPeripheral,
198            service: &String,
199            characteristic: &String,
200            descriptor: &String,
201            data: &Vec<u8>,
202        ) -> Result<()>;
203
204        // RustyService functions
205
206        fn uuid(self: &RustyService) -> String;
207        fn data(self: &RustyService) -> Vec<u8>;
208        fn characteristics(self: &RustyService) -> Vec<RustyCharacteristicWrapper>;
209
210        // RustyCharacteristic functions
211
212        fn uuid(self: &RustyCharacteristic) -> String;
213        fn descriptors(self: &RustyCharacteristic) -> Vec<RustyDescriptorWrapper>;
214
215        fn can_read(self: &RustyCharacteristic) -> bool;
216        fn can_write_request(self: &RustyCharacteristic) -> bool;
217        fn can_write_command(self: &RustyCharacteristic) -> bool;
218        fn can_notify(self: &RustyCharacteristic) -> bool;
219        fn can_indicate(self: &RustyCharacteristic) -> bool;
220
221        // RustyDescriptor functions
222
223        fn uuid(self: &RustyDescriptor) -> String;
224    }
225}
226
227