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 std::sync::atomic::{AtomicU8, Ordering}; 9 10use uuid::{Uuid, uuid}; 11 12use crate::device::{ 13 hardware::{HardwareCommand, HardwareWriteCmd}, 14 protocol::{ProtocolHandler, generic_protocol_setup}, 15}; 16use buttplug_core::errors::ButtplugDeviceError; 17use buttplug_server_device_config::Endpoint; 18 19const JOYHUB_PROTOCOL_UUID: Uuid = uuid!("c0f6785a-0056-4a2a-a2a9-dc7ca4ae2a0d"); 20 21generic_protocol_setup!(JoyHub, "joyhub"); 22 23#[derive(Default)] 24pub struct JoyHub { 25 last_cmds: [AtomicU8; 3], 26} 27 28impl JoyHub { 29 fn form_hardware_command( 30 &self, 31 index: u32, 32 speed: u32, 33 ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 34 self.last_cmds[index as usize].store(speed as u8, Ordering::Relaxed); 35 Ok(vec![ 36 HardwareWriteCmd::new( 37 &[JOYHUB_PROTOCOL_UUID], 38 Endpoint::Tx, 39 vec![ 40 0xa0, 41 0x03, 42 self.last_cmds[0].load(Ordering::Relaxed), 43 self.last_cmds[2].load(Ordering::Relaxed), 44 self.last_cmds[1].load(Ordering::Relaxed), 45 0x00, 46 0xaa, 47 ], 48 false, 49 ) 50 .into(), 51 ]) 52 } 53} 54 55impl ProtocolHandler for JoyHub { 56 fn handle_output_vibrate_cmd( 57 &self, 58 feature_index: u32, 59 _feature_id: Uuid, 60 speed: u32, 61 ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 62 self.form_hardware_command(feature_index, speed) 63 } 64 65 fn handle_output_rotate_cmd( 66 &self, 67 feature_index: u32, 68 _feature_id: Uuid, 69 speed: i32, 70 ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 71 self.form_hardware_command(feature_index, speed as u32) 72 } 73 74 fn handle_output_oscillate_cmd( 75 &self, 76 feature_index: u32, 77 _feature_id: Uuid, 78 speed: u32, 79 ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 80 self.form_hardware_command(feature_index, speed) 81 } 82 83 fn handle_output_constrict_cmd( 84 &self, 85 _feature_index: u32, 86 feature_id: Uuid, 87 level: u32, 88 ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 89 Ok(vec![ 90 HardwareWriteCmd::new( 91 &[feature_id], 92 Endpoint::Tx, 93 vec![ 94 0xa0, 95 0x07, 96 if level == 0 { 0x00 } else { 0x01 }, 97 0x00, 98 level as u8, 99 0xff, 100 ], 101 false, 102 ) 103 .into(), 104 ]) 105 } 106}