Buttplug sex toy control library
1// Buttplug Rust Source Code File - See https://buttplug.io for more info.
2//
3// Copyright 2016-2025 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
19generic_protocol_setup!(SexverseLG389, "sexverse-lg389");
20
21const SEXVERSE_PROTOCOL_UUID: Uuid = uuid!("575b2394-8f88-4367-a355-11321efda686");
22
23#[derive(Default)]
24pub struct SexverseLG389 {
25 vibe_speed: AtomicU8,
26 osc_speed: AtomicU8,
27}
28
29impl SexverseLG389 {
30 fn generate_command(&self) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
31 let vibe = self.vibe_speed.load(Ordering::Relaxed);
32 let osc = self.osc_speed.load(Ordering::Relaxed);
33 let range = if osc == 0 { 0 } else { 4u8 }; // Full range
34 let anchor = if osc == 0 { 0 } else { 1u8 }; // Anchor to base
35 Ok(vec![
36 HardwareWriteCmd::new(
37 &[SEXVERSE_PROTOCOL_UUID],
38 Endpoint::Tx,
39 vec![0xaa, 0x05, vibe, 0x14, anchor, 0x00, range, 0x00, osc, 0x00],
40 true,
41 )
42 .into(),
43 ])
44 }
45}
46
47impl ProtocolHandler for SexverseLG389 {
48 fn handle_output_vibrate_cmd(
49 &self,
50 _feature_index: u32,
51 _feature_id: uuid::Uuid,
52 speed: u32,
53 ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
54 self.vibe_speed.store(speed as u8, Ordering::Relaxed);
55 self.generate_command()
56 }
57
58 fn handle_output_oscillate_cmd(
59 &self,
60 _feature_index: u32,
61 _feature_id: uuid::Uuid,
62 speed: u32,
63 ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
64 self.osc_speed.store(speed as u8, Ordering::Relaxed);
65 self.generate_command()
66 }
67}