Buttplug sex toy control library
1// Buttplug Rust Source Code File - See https://buttplug.io for more info. 2// 3// Copyright 2016-2024 Nonpolynomial Labs LLC. All rights reserved. 4// 5// Licensed under the BSD 3-Clause license. See LICENSE file in the project root 6// for full license information. 7 8use crate::device::{ 9 hardware::{Hardware, HardwareCommand, HardwareWriteCmd}, 10 protocol::{ 11 ProtocolHandler, 12 ProtocolIdentifier, 13 ProtocolInitializer, 14 ProtocolKeepaliveStrategy, 15 generic_protocol_initializer_setup, 16 }, 17}; 18use async_trait::async_trait; 19use buttplug_core::errors::ButtplugDeviceError; 20use buttplug_server_device_config::Endpoint; 21use buttplug_server_device_config::{ 22 ProtocolCommunicationSpecifier, 23 ServerDeviceDefinition, 24 UserDeviceIdentifier, 25}; 26use std::sync::Arc; 27use std::time::Duration; 28use uuid::{Uuid, uuid}; 29 30const LETEN_PROTOCOL_UUID: Uuid = uuid!("7d899f44-2676-4a00-9c68-0c800055ee2a"); 31 32generic_protocol_initializer_setup!(Leten, "leten"); 33#[derive(Default)] 34pub struct LetenInitializer {} 35 36#[async_trait] 37impl ProtocolInitializer for LetenInitializer { 38 async fn initialize( 39 &mut self, 40 hardware: Arc<Hardware>, 41 _: &ServerDeviceDefinition, 42 ) -> Result<Arc<dyn ProtocolHandler>, ButtplugDeviceError> { 43 // There's a more complex auth flow that the app "sometimes" goes through where it 44 // sends [0x04, 0x00] and waits for [0x01] on Rx before calling [0x04, 0x01] 45 hardware 46 .write_value(&HardwareWriteCmd::new( 47 &[LETEN_PROTOCOL_UUID], 48 Endpoint::Tx, 49 vec![0x04, 0x01], 50 true, 51 )) 52 .await?; 53 // Sometimes sending this causes Rx to receive [0x0a] 54 Ok(Arc::new(Leten::default())) 55 } 56} 57 58const LETEN_COMMAND_DELAY_MS: u64 = 1000; 59 60#[derive(Default)] 61pub struct Leten {} 62 63impl ProtocolHandler for Leten { 64 fn keepalive_strategy(&self) -> ProtocolKeepaliveStrategy { 65 // Leten keepalive is shorter 66 ProtocolKeepaliveStrategy::RepeatLastPacketStrategyWithTiming(Duration::from_millis( 67 LETEN_COMMAND_DELAY_MS, 68 )) 69 } 70 71 fn handle_output_vibrate_cmd( 72 &self, 73 _feature_index: u32, 74 feature_id: Uuid, 75 speed: u32, 76 ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 77 Ok(vec![ 78 HardwareWriteCmd::new(&[feature_id], Endpoint::Tx, vec![0x02, speed as u8], true).into(), 79 ]) 80 } 81}