Buttplug sex toy control library
at dev 150 lines 4.1 kB view raw
1use super::hidapi_async::HidAsyncDevice; 2use async_trait::async_trait; 3use buttplug_core::errors::ButtplugDeviceError; 4use buttplug_server::device::hardware::{ 5 GenericHardwareSpecializer, 6 Hardware, 7 HardwareConnector, 8 HardwareEvent, 9 HardwareInternal, 10 HardwareReadCmd, 11 HardwareReading, 12 HardwareSpecializer, 13 HardwareSubscribeCmd, 14 HardwareUnsubscribeCmd, 15 HardwareWriteCmd, 16}; 17use buttplug_server_device_config::{Endpoint, ProtocolCommunicationSpecifier, VIDPIDSpecifier}; 18use futures::{AsyncWriteExt, future::BoxFuture}; 19use hidapi::{DeviceInfo, HidApi}; 20use std::{ 21 fmt::{self, Debug}, 22 sync::{ 23 Arc, 24 atomic::{AtomicBool, Ordering}, 25 }, 26}; 27use tokio::sync::{Mutex, broadcast}; 28 29pub struct HidHardwareConnector { 30 hid_instance: Arc<HidApi>, 31 device_info: DeviceInfo, 32} 33 34impl HidHardwareConnector { 35 pub fn new(hid_instance: Arc<HidApi>, device_info: &DeviceInfo) -> Self { 36 Self { 37 hid_instance, 38 device_info: device_info.clone(), 39 } 40 } 41} 42 43impl Debug for HidHardwareConnector { 44 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 45 f.debug_struct("HIDHardwareConnector") 46 .field("vid", &self.device_info.vendor_id()) 47 .field("pid", &self.device_info.product_id()) 48 .finish() 49 } 50} 51 52#[async_trait] 53impl HardwareConnector for HidHardwareConnector { 54 fn specifier(&self) -> ProtocolCommunicationSpecifier { 55 info!( 56 "Specifier for {}: {:#04x} {:#04x}", 57 self.device_info.product_string().unwrap(), 58 self.device_info.vendor_id(), 59 self.device_info.product_id() 60 ); 61 ProtocolCommunicationSpecifier::HID(VIDPIDSpecifier::new( 62 self.device_info.vendor_id(), 63 self.device_info.product_id(), 64 )) 65 } 66 67 async fn connect(&mut self) -> Result<Box<dyn HardwareSpecializer>, ButtplugDeviceError> { 68 let device = self.device_info.open_device(&self.hid_instance).unwrap(); 69 let device_impl_internal = HIDDeviceImpl::new(HidAsyncDevice::new(device).unwrap()); 70 info!( 71 "New HID device created: {}", 72 self.device_info.product_string().unwrap() 73 ); 74 let hardware = Hardware::new( 75 self.device_info.product_string().unwrap(), 76 self.device_info.serial_number().unwrap(), 77 &[Endpoint::Rx, Endpoint::Tx], 78 &None, 79 false, 80 Box::new(device_impl_internal), 81 ); 82 Ok(Box::new(GenericHardwareSpecializer::new(hardware))) 83 } 84} 85 86pub struct HIDDeviceImpl { 87 connected: Arc<AtomicBool>, 88 device_event_sender: broadcast::Sender<HardwareEvent>, 89 device: Arc<Mutex<HidAsyncDevice>>, 90} 91 92impl HIDDeviceImpl { 93 pub fn new(device: HidAsyncDevice) -> Self { 94 let (device_event_sender, _) = broadcast::channel(256); 95 Self { 96 device: Arc::new(Mutex::new(device)), 97 connected: Arc::new(AtomicBool::new(true)), 98 device_event_sender, 99 } 100 } 101} 102 103impl HardwareInternal for HIDDeviceImpl { 104 fn event_stream(&self) -> broadcast::Receiver<HardwareEvent> { 105 self.device_event_sender.subscribe() 106 } 107 108 fn disconnect(&self) -> BoxFuture<'static, Result<(), ButtplugDeviceError>> { 109 let connected = self.connected.clone(); 110 Box::pin(async move { 111 connected.store(false, Ordering::Relaxed); 112 Ok(()) 113 }) 114 } 115 116 fn read_value( 117 &self, 118 _msg: &HardwareReadCmd, 119 ) -> BoxFuture<'static, Result<HardwareReading, ButtplugDeviceError>> { 120 unimplemented!(); 121 } 122 123 fn write_value( 124 &self, 125 msg: &HardwareWriteCmd, 126 ) -> BoxFuture<'static, Result<(), ButtplugDeviceError>> { 127 let device = self.device.clone(); 128 let data = msg.data().clone(); 129 Box::pin(async move { 130 device.lock().await.write(&data).await.map_err(|e| { 131 ButtplugDeviceError::DeviceCommunicationError(format!("Cannot write to HID Device: {e:?}.")) 132 })?; 133 Ok(()) 134 }) 135 } 136 137 fn subscribe( 138 &self, 139 _msg: &HardwareSubscribeCmd, 140 ) -> BoxFuture<'static, Result<(), ButtplugDeviceError>> { 141 unimplemented!(); 142 } 143 144 fn unsubscribe( 145 &self, 146 _msg: &HardwareUnsubscribeCmd, 147 ) -> BoxFuture<'static, Result<(), ButtplugDeviceError>> { 148 unimplemented!(); 149 } 150}