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 FEELINGSO_PROTOCOL_UUID: Uuid = uuid!("397d4cce-3173-4f66-b7ad-6ee21e59f854");
20
21generic_protocol_setup!(FeelingSo, "feelingso");
22
23pub struct FeelingSo {
24 speeds: [AtomicU8; 2],
25}
26
27impl Default for FeelingSo {
28 fn default() -> Self {
29 Self {
30 speeds: [AtomicU8::new(0), AtomicU8::new(0)],
31 }
32 }
33}
34
35impl FeelingSo {
36 fn hardware_command(&self) -> Vec<HardwareCommand> {
37 vec![
38 HardwareWriteCmd::new(
39 &[FEELINGSO_PROTOCOL_UUID],
40 Endpoint::Tx,
41 vec![
42 0xaa,
43 0x40,
44 0x03,
45 self.speeds[0].load(Ordering::Relaxed),
46 self.speeds[1].load(Ordering::Relaxed),
47 0x14, // Oscillate range: 1 to 4
48 0x19, // Checksum?
49 ],
50 false,
51 )
52 .into(),
53 ]
54 }
55}
56
57impl ProtocolHandler for FeelingSo {
58 fn handle_output_oscillate_cmd(
59 &self,
60 _feature_index: u32,
61 _feature_id: Uuid,
62 speed: u32,
63 ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
64 self.speeds[1].store(speed as u8, Ordering::Relaxed);
65 Ok(self.hardware_command())
66 }
67
68 fn handle_output_vibrate_cmd(
69 &self,
70 _feature_index: u32,
71 _feature_id: Uuid,
72 speed: u32,
73 ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
74 self.speeds[0].store(speed as u8, Ordering::Relaxed);
75 Ok(self.hardware_command())
76 }
77}