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 uuid::Uuid;
9
10use buttplug_core::errors::ButtplugDeviceError;
11use buttplug_server_device_config::Endpoint;
12
13use crate::device::{
14 hardware::{HardwareCommand, HardwareWriteCmd},
15 protocol::{ProtocolHandler, generic_protocol_setup},
16};
17use std::sync::atomic::{AtomicU8, Ordering};
18
19generic_protocol_setup!(TryFunMeta2, "tryfun-meta2");
20
21#[derive(Default)]
22pub struct TryFunMeta2 {
23 packet_id: AtomicU8,
24}
25
26impl ProtocolHandler for TryFunMeta2 {
27 fn handle_output_oscillate_cmd(
28 &self,
29 _feature_index: u32,
30 feature_id: Uuid,
31 speed: u32,
32 ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
33 let mut sum: u8 = 0xff;
34 let mut data = vec![
35 self.packet_id.fetch_add(1, Ordering::Relaxed),
36 0x02,
37 0x00,
38 0x05,
39 0x21,
40 0x05,
41 0x0b,
42 speed as u8,
43 ];
44 let mut count = 1;
45 for item in data.iter().skip(1) {
46 sum -= item;
47 count += 1;
48 }
49 sum += count;
50 data.push(sum);
51
52 Ok(vec![
53 HardwareWriteCmd::new(&[feature_id], Endpoint::Tx, data, false).into(),
54 ])
55 }
56
57 fn handle_output_rotate_cmd(
58 &self,
59 _feature_index: u32,
60 feature_id: Uuid,
61 speed: i32,
62 ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
63 let mut speed = speed as i8;
64 if speed >= 0 {
65 speed += 1;
66 }
67 speed *= -1;
68 let mut sum: u8 = 0xff;
69 let mut data = vec![
70 self.packet_id.fetch_add(1, Ordering::Relaxed),
71 0x02,
72 0x00,
73 0x05,
74 0x21,
75 0x05,
76 0x0e,
77 speed as u8,
78 ];
79 let mut count = 1;
80 for item in data.iter().skip(1) {
81 sum = sum.wrapping_sub(*item);
82 count += 1;
83 }
84 sum += count;
85 data.push(sum);
86 Ok(vec![
87 HardwareWriteCmd::new(&[feature_id], Endpoint::Tx, data, false).into(),
88 ])
89 }
90
91 fn handle_output_vibrate_cmd(
92 &self,
93 _feature_index: u32,
94 feature_id: Uuid,
95 speed: u32,
96 ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
97 let mut sum: u8 = 0xff;
98 let mut data = vec![
99 self.packet_id.fetch_add(1, Ordering::Relaxed),
100 0x02,
101 0x00,
102 0x05,
103 0x21,
104 0x05,
105 0x08,
106 speed as u8,
107 ];
108 let mut count = 1;
109 for item in data.iter().skip(1) {
110 sum -= item;
111 count += 1;
112 }
113 sum += count;
114 data.push(sum);
115
116 Ok(vec![
117 HardwareWriteCmd::new(&[feature_id], Endpoint::Tx, data, false).into(),
118 ])
119 }
120}