Buttplug sex toy control library
at master 115 lines 2.9 kB view raw
1// Buttplug Rust Source Code File - See https://buttplug.io for more info. 2// 3// Copyright 2016-2023 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::protocol::ProtocolKeepaliveStrategy; 9use crate::device::{ 10 hardware::{Hardware, HardwareCommand, HardwareSubscribeCmd, HardwareWriteCmd}, 11 protocol::{ 12 ProtocolHandler, 13 ProtocolIdentifier, 14 ProtocolInitializer, 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 uuid::{Uuid, uuid}; 28 29generic_protocol_initializer_setup!(SvakomSam, "svakom-sam"); 30const SVAKOM_SAM_PROTOCOL_UUID: Uuid = uuid!("e39a6b4a-230a-4669-be94-68135f97f166"); 31 32#[derive(Default)] 33pub struct SvakomSamInitializer {} 34 35#[async_trait] 36impl ProtocolInitializer for SvakomSamInitializer { 37 async fn initialize( 38 &mut self, 39 hardware: Arc<Hardware>, 40 _: &ServerDeviceDefinition, 41 ) -> Result<Arc<dyn ProtocolHandler>, ButtplugDeviceError> { 42 hardware 43 .subscribe(&HardwareSubscribeCmd::new( 44 SVAKOM_SAM_PROTOCOL_UUID, 45 Endpoint::Rx, 46 )) 47 .await?; 48 let mut gen2 = hardware.endpoints().contains(&Endpoint::TxMode); 49 if !gen2 && hardware.endpoints().contains(&Endpoint::Firmware) { 50 gen2 = true; 51 warn!( 52 "Svakom Sam model without speed control detected - This device will only vibrate at 1 speed" 53 ); 54 } 55 56 Ok(Arc::new(SvakomSam::new(gen2))) 57 } 58} 59 60pub struct SvakomSam { 61 gen2: bool, 62} 63 64impl SvakomSam { 65 pub fn new(gen2: bool) -> Self { 66 Self { gen2 } 67 } 68} 69 70impl ProtocolHandler for SvakomSam { 71 fn keepalive_strategy(&self) -> ProtocolKeepaliveStrategy { 72 ProtocolKeepaliveStrategy::HardwareRequiredRepeatLastPacketStrategy 73 } 74 75 fn handle_output_vibrate_cmd( 76 &self, 77 feature_index: u32, 78 feature_id: Uuid, 79 speed: u32, 80 ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 81 if feature_index == 0 { 82 Ok(vec![ 83 HardwareWriteCmd::new( 84 &[feature_id], 85 Endpoint::Tx, 86 if self.gen2 { 87 [ 88 18, 89 1, 90 3, 91 0, 92 if speed == 0 { 0x00 } else { 0x04 }, 93 speed as u8, 94 ] 95 .to_vec() 96 } else { 97 [18, 1, 3, 0, 5, speed as u8].to_vec() 98 }, 99 false, 100 ) 101 .into(), 102 ]) 103 } else { 104 Ok(vec![ 105 HardwareWriteCmd::new( 106 &[feature_id], 107 Endpoint::Tx, 108 [18, 6, 1, speed as u8].to_vec(), 109 false, 110 ) 111 .into(), 112 ]) 113 } 114 } 115}