Add donglora-client (clients/rust/) and donglora-mux (mux/rust/) as Rust implementations of the existing Python client library and mux daemon. Both are standalone Cargo projects with no-panic guarantees enforced by clippy deny lints. donglora-client provides protocol types, COBS framing, USB device discovery, serial/mux transports, and a high-level Client<T> with send/recv. donglora-mux is a fully async (tokio) multiplexer daemon with dongle hot-plug reconnect, per-client bounded send queues, SetConfig locking, and StartRx/StopRx reference counting. 52 unit tests across both crates. Updates README roadmap checkboxes and CONTRIBUTING docs to reflect the new implementations.
48 lines
1.3 KiB
Rust
48 lines
1.3 KiB
Rust
//! USB device discovery for DongLoRa dongles.
|
|
//!
|
|
//! Finds the serial port by matching USB VID:PID using the `serialport` crate.
|
|
|
|
use std::thread;
|
|
use std::time::Duration;
|
|
|
|
use tracing::info;
|
|
|
|
/// DongLoRa USB Vendor ID.
|
|
pub const USB_VID: u16 = 0x1209;
|
|
|
|
/// DongLoRa USB Product ID.
|
|
pub const USB_PID: u16 = 0x5741;
|
|
|
|
/// Find the DongLoRa serial port by USB VID:PID.
|
|
///
|
|
/// Returns the first matching port path, or `None` if no device is found.
|
|
pub fn find_port() -> Option<String> {
|
|
let ports = serialport::available_ports().ok()?;
|
|
ports
|
|
.into_iter()
|
|
.find(|p| {
|
|
matches!(
|
|
&p.port_type,
|
|
serialport::SerialPortType::UsbPort(info)
|
|
if info.vid == USB_VID && info.pid == USB_PID
|
|
)
|
|
})
|
|
.map(|p| p.port_name)
|
|
}
|
|
|
|
/// Block until a DongLoRa device appears on USB.
|
|
///
|
|
/// Polls [`find_port`] every 500ms and returns the port path once found.
|
|
pub fn wait_for_device() -> String {
|
|
info!("waiting for DongLoRa device...");
|
|
loop {
|
|
if let Some(port) = find_port() {
|
|
info!("found device at {port}");
|
|
// Brief delay for USB enumeration to settle
|
|
thread::sleep(Duration::from_millis(300));
|
|
return port;
|
|
}
|
|
thread::sleep(Duration::from_millis(500));
|
|
}
|
|
}
|