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 COWGIRL_PROTOCOL_UUID: Uuid = uuid!("0474d2fd-f566-4bed-8770-88e457a96144");
20generic_protocol_setup!(Cowgirl, "cowgirl");
21
22pub struct Cowgirl {
23 speeds: [AtomicU8; 2],
24}
25
26impl Default for Cowgirl {
27 fn default() -> Self {
28 Self {
29 speeds: [AtomicU8::new(0), AtomicU8::new(0)],
30 }
31 }
32}
33
34impl Cowgirl {
35 fn hardware_commands(&self) -> Vec<HardwareCommand> {
36 vec![
37 HardwareWriteCmd::new(
38 &[COWGIRL_PROTOCOL_UUID],
39 Endpoint::Tx,
40 vec![
41 0x00,
42 0x01,
43 self.speeds[0].load(Ordering::Relaxed),
44 self.speeds[1].load(Ordering::Relaxed),
45 ],
46 true,
47 )
48 .into(),
49 ]
50 }
51}
52
53impl ProtocolHandler for Cowgirl {
54 fn handle_output_vibrate_cmd(
55 &self,
56 _feature_index: u32,
57 _feature_id: Uuid,
58 speed: u32,
59 ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
60 self.speeds[0].store(speed as u8, Ordering::Relaxed);
61 Ok(self.hardware_commands())
62 }
63
64 fn handle_output_rotate_cmd(
65 &self,
66 _feature_index: u32,
67 _feature_id: Uuid,
68 speed: i32,
69 ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
70 self.speeds[1].store(speed as u8, Ordering::Relaxed);
71 Ok(self.hardware_commands())
72 }
73}