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 HTK_BM_PROTOCOL_UUID: Uuid = uuid!("4c70cb95-d3d9-4288-81ab-be845f9ad1fe");
20generic_protocol_setup!(HtkBm, "htk_bm");
21
22pub struct HtkBm {
23 speeds: [AtomicU8; 2],
24}
25
26impl Default for HtkBm {
27 fn default() -> Self {
28 Self {
29 speeds: [AtomicU8::new(0), AtomicU8::new(0)],
30 }
31 }
32}
33
34impl ProtocolHandler for HtkBm {
35 fn handle_output_vibrate_cmd(
36 &self,
37 feature_index: u32,
38 _feature_id: Uuid,
39 speed: u32,
40 ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
41 self.speeds[feature_index as usize].store(speed as u8, Ordering::Relaxed);
42
43 let mut data: u8 = 15;
44 let left = self.speeds[0].load(Ordering::Relaxed);
45 let right = self.speeds[1].load(Ordering::Relaxed);
46 if left != 0 && right != 0 {
47 data = 11 // both (normal mode)
48 } else if left != 0 {
49 data = 12 // left only
50 } else if right != 0 {
51 data = 13 // right only
52 }
53 Ok(vec![
54 HardwareWriteCmd::new(&[HTK_BM_PROTOCOL_UUID], Endpoint::Tx, vec![data], false).into(),
55 ])
56 }
57}