usbip-rs/lib/examples/hid_keyboard.rs
Davíð Steinn Geirsson 30d3c9532e feat: add usbip-rs CLI tool with vsock transport
Convert to cargo workspace with lib/ and cli/ crates. Add Nix flake
for building and development. Extract handle_urb_loop and add
read_urb_command to the library for CLI consumption.

Implement the usbip-rs CLI binary with clap subcommands:
- client listen: accept incoming connections via vhci_hcd sysfs
- host connect: passthrough real USB devices via nusb
- test_hid connect: export a simulated HID keyboard for testing

Add vsock transport layer and vhci_hcd sysfs interaction module.
Apply rustfmt formatting project-wide and add rustfmt/clippy to devShell.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 10:41:42 +00:00

44 lines
1.4 KiB
Rust

use log::*;
use std::net::*;
use std::sync::{Arc, Mutex};
use std::time::Duration;
#[tokio::main]
async fn main() {
env_logger::init();
let handler = Arc::new(Mutex::new(
Box::new(usbip_rs::hid::UsbHidKeyboardHandler::new_keyboard())
as Box<dyn usbip_rs::UsbInterfaceHandler + Send>,
));
let server = Arc::new(usbip_rs::UsbIpServer::new_simulated(vec![
usbip_rs::UsbDevice::new(0).with_interface(
usbip_rs::ClassCode::HID as u8,
0x00,
0x00,
Some("Test HID"),
vec![usbip_rs::UsbEndpoint {
address: 0x81, // IN
attributes: 0x03, // Interrupt
max_packet_size: 0x08, // 8 bytes
interval: 10,
}],
handler.clone(),
),
]));
let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 3240);
tokio::spawn(usbip_rs::server(addr, server));
loop {
// sleep 1s
tokio::time::sleep(Duration::new(1, 0)).await;
let mut handler = handler.lock().unwrap();
if let Some(hid) = handler
.as_any()
.downcast_mut::<usbip_rs::hid::UsbHidKeyboardHandler>()
{
hid.pending_key_events
.push_back(usbip_rs::hid::UsbHidKeyboardReport::from_ascii(b'1'));
info!("Simulate a key event");
}
}
}