netget/server/usb/mouse/
handler.rs1#[cfg(all(unix, feature = "libusb"))]
10use crate::server::usb::descriptors::{build_hid_mouse_report_descriptor, MouseReport};
11#[cfg(all(unix, feature = "libusb"))]
12use std::collections::VecDeque;
13#[cfg(all(unix, feature = "libusb"))]
14use tracing::{debug, trace, warn};
15
16#[cfg(all(unix, feature = "libusb"))]
18mod hid_descriptor_type {
19 pub const HID: u8 = 0x21;
20 pub const REPORT: u8 = 0x22;
21}
22
23#[cfg(all(unix, feature = "libusb"))]
25#[derive(Debug)]
26pub struct UsbHidMouseHandler {
27 report_descriptor: Vec<u8>,
29 pending_reports: VecDeque<[u8; 4]>,
31}
32
33#[cfg(all(unix, feature = "libusb"))]
34impl Default for UsbHidMouseHandler {
35 fn default() -> Self {
36 Self::new()
37 }
38}
39
40#[cfg(all(unix, feature = "libusb"))]
41impl UsbHidMouseHandler {
42 pub fn new() -> Self {
43 Self {
44 report_descriptor: build_hid_mouse_report_descriptor(),
45 pending_reports: VecDeque::new(),
46 }
47 }
48
49 pub fn endpoints() -> Vec<usbip::UsbEndpoint> {
51 vec![usbip::UsbEndpoint {
52 address: 0x81, attributes: 0x03, max_packet_size: 4, interval: 10, }]
57 }
58
59 pub fn queue(&mut self, report: MouseReport) {
61 trace!(
62 "USB mouse queue report: buttons={:#04x} x={} y={} wheel={}",
63 report.buttons,
64 report.x,
65 report.y,
66 report.wheel
67 );
68 self.pending_reports.push_back(report.to_bytes());
69 }
70
71 pub fn queue_with_release(&mut self, report: MouseReport) {
76 let held = report.buttons != 0;
77 self.queue(report);
78 if held {
79 self.queue(MouseReport::new());
80 }
81 }
82
83 #[allow(dead_code)]
85 pub fn pending_len(&self) -> usize {
86 self.pending_reports.len()
87 }
88}
89
90#[cfg(all(unix, feature = "libusb"))]
91impl usbip::UsbInterfaceHandler for UsbHidMouseHandler {
92 fn handle_urb(
93 &mut self,
94 _interface: &usbip::UsbInterface,
95 ep: usbip::UsbEndpoint,
96 _transfer_buffer_length: u32,
97 setup: usbip::SetupPacket,
98 _req: &[u8],
99 ) -> std::result::Result<Vec<u8>, std::io::Error> {
100 if ep.is_ep0() {
101 match (setup.request_type, setup.request) {
103 (0b1000_0001, 0x06) => {
105 let desc_type = (setup.value >> 8) as u8;
106 if desc_type == hid_descriptor_type::REPORT {
107 debug!(
108 "USB mouse GET_DESCRIPTOR(Report): {} bytes",
109 self.report_descriptor.len()
110 );
111 Ok(self.report_descriptor.clone())
112 } else {
113 warn!("USB mouse: unsupported descriptor type {:#04x}", desc_type);
114 Ok(vec![])
115 }
116 }
117 (0b0010_0001, 0x0A) | (0b0010_0001, 0x0B) => Ok(vec![]),
119 (0b1010_0001, 0x01) => Ok(self
121 .pending_reports
122 .front()
123 .map(|r| r.to_vec())
124 .unwrap_or_else(|| vec![0u8; 4])),
125 _ => {
126 debug!(
130 "USB mouse: unhandled control request type={:#04x} request={:#04x}",
131 setup.request_type, setup.request
132 );
133 Ok(vec![])
134 }
135 }
136 } else if let usbip::Direction::In = ep.direction() {
137 Ok(self
139 .pending_reports
140 .pop_front()
141 .map(|r| r.to_vec())
142 .unwrap_or_default())
143 } else {
144 Ok(vec![])
146 }
147 }
148
149 fn get_class_specific_descriptor(&self) -> Vec<u8> {
150 let len = self.report_descriptor.len();
151 vec![
152 0x09, hid_descriptor_type::HID, 0x11,
155 0x01, 0x00, 0x01, hid_descriptor_type::REPORT, len as u8,
160 (len >> 8) as u8, ]
162 }
163
164 fn as_any(&mut self) -> &mut dyn std::any::Any {
165 self
166 }
167}