| 1 | //! Device plugins. |
| 2 | //! |
| 3 | //! To support a new pair of buds, add one module here and list it in [`REGISTRY`]. Transport, |
| 4 | //! CLI and GUI code do not change. |
| 5 | |
| 6 | use crate::bluez::PairedDevice; |
| 7 | use crate::bt::Uuid; |
| 8 | use crate::error::{Error, Result}; |
| 9 | use crate::status::{NoiseControl, NoiseMode, Status, TouchControls}; |
| 10 | use crate::transport::Transport; |
| 11 | |
| 12 | pub mod realme_t310; |
| 13 | |
| 14 | /// Every model budctl supports. |
| 15 | pub static REGISTRY: &[&dyn Device] = &[&realme_t310::RealmeT310]; |
| 16 | |
| 17 | /// One supported model. |
| 18 | pub trait Device: Sync { |
| 19 | /// Model name, e.g. `realme Buds T310`. |
| 20 | fn name(&self) -> &'static str; |
| 21 | |
| 22 | /// Whether a paired device is this model, judged from BlueZ data alone. |
| 23 | fn matches(&self, device: &PairedDevice) -> bool; |
| 24 | |
| 25 | /// The control service(s), in the order to try. SDP turns each into an RFCOMM channel. |
| 26 | fn rfcomm_uuids(&self) -> &'static [Uuid]; |
| 27 | |
| 28 | /// Run the model's init sequence on a fresh link and return a ready session. |
| 29 | fn open(&self, link: Box<dyn Transport>) -> Result<Box<dyn Session>>; |
| 30 | } |
| 31 | |
| 32 | /// An open control link to one pair of buds. Dropping it closes the link. |
| 33 | pub trait Session: Send { |
| 34 | /// Battery, noise control, EQ, switches and whatever else the model can read. |
| 35 | fn status(&mut self) -> Result<Status>; |
| 36 | |
| 37 | /// The touch-control (gesture) settings of each bud. |
| 38 | fn touch_controls(&mut self) -> Result<TouchControls> { |
| 39 | Err(Error::Unsupported( |
| 40 | "these buds have no touch-control settings budctl can read".to_owned(), |
| 41 | )) |
| 42 | } |
| 43 | |
| 44 | /// Set the noise-control mode, then read it back. Returns the mode the buds now report. |
| 45 | fn set_noise_control(&mut self, _mode: NoiseMode) -> Result<NoiseControl> { |
| 46 | Err(Error::Unsupported( |
| 47 | "these buds have no noise-control setting budctl can change".to_owned(), |
| 48 | )) |
| 49 | } |
| 50 | } |
| 51 | |
| 52 | /// The supported model a paired device is, if any. |
| 53 | pub fn identify(device: &PairedDevice) -> Option<&'static dyn Device> { |
| 54 | REGISTRY.iter().copied().find(|model| model.matches(device)) |
| 55 | } |