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 crate::device::hardware::Hardware;
9use crate::device::protocol::ProtocolInitializer;
10use crate::device::{
11 hardware::{HardwareCommand, HardwareWriteCmd},
12 protocol::{ProtocolHandler, ProtocolIdentifier, generic_protocol_initializer_setup},
13};
14use async_trait::async_trait;
15use buttplug_core::errors::ButtplugDeviceError;
16use buttplug_server_device_config::Endpoint;
17use buttplug_server_device_config::{
18 ProtocolCommunicationSpecifier,
19 ServerDeviceDefinition,
20 UserDeviceIdentifier,
21};
22use std::sync::Arc;
23use uuid::{Uuid, uuid};
24
25const SEXVERSE_V2_PROTOCOL_ID: Uuid = uuid!("28b934b4-ca45-4e14-85e7-4c1524b2b4c1");
26generic_protocol_initializer_setup!(SexverseV2, "sexverse-v2");
27
28#[derive(Default)]
29pub struct SexverseV2Initializer {}
30
31#[async_trait]
32impl ProtocolInitializer for SexverseV2Initializer {
33 async fn initialize(
34 &mut self,
35 hardware: Arc<Hardware>,
36 _: &ServerDeviceDefinition,
37 ) -> Result<Arc<dyn ProtocolHandler>, ButtplugDeviceError> {
38 hardware
39 .write_value(&HardwareWriteCmd::new(
40 &[SEXVERSE_V2_PROTOCOL_ID],
41 Endpoint::Tx,
42 vec![0xaa, 0x04],
43 true,
44 ))
45 .await?;
46 Ok(Arc::new(SexverseV2::default()))
47 }
48}
49
50#[derive(Default)]
51pub struct SexverseV2 {}
52
53impl SexverseV2 {
54 fn form_command(
55 &self,
56 feature_index: u32,
57 feature_id: Uuid,
58 speed: u32,
59 ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
60 Ok(vec![
61 HardwareWriteCmd::new(
62 &[feature_id],
63 Endpoint::Tx,
64 vec![
65 0xaa,
66 0x03,
67 0x01,
68 (feature_index + 1) as u8,
69 0x64,
70 speed as u8,
71 ],
72 true,
73 )
74 .into(),
75 ])
76 }
77}
78
79impl ProtocolHandler for SexverseV2 {
80 fn handle_output_vibrate_cmd(
81 &self,
82 feature_index: u32,
83 feature_id: Uuid,
84 speed: u32,
85 ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
86 self.form_command(feature_index, feature_id, speed)
87 }
88
89 fn handle_output_oscillate_cmd(
90 &self,
91 feature_index: u32,
92 feature_id: Uuid,
93 speed: u32,
94 ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
95 self.form_command(feature_index, feature_id, speed)
96 }
97}