fork
Configure Feed
Select the types of activity you want to include in your feed.
Buttplug sex toy control library
fork
Configure Feed
Select the types of activity you want to include in your feed.
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 crate::device::{
9 hardware::{Hardware, HardwareCommand, HardwareWriteCmd},
10 protocol::{
11 ProtocolHandler,
12 ProtocolIdentifier,
13 ProtocolInitializer,
14 ProtocolKeepaliveStrategy,
15 generic_protocol_initializer_setup,
16 },
17};
18use async_trait::async_trait;
19use buttplug_core::errors::ButtplugDeviceError;
20use buttplug_server_device_config::Endpoint;
21use buttplug_server_device_config::{
22 ProtocolCommunicationSpecifier,
23 ServerDeviceDefinition,
24 UserDeviceIdentifier,
25};
26use std::{
27 sync::{
28 Arc,
29 atomic::{AtomicU8, Ordering},
30 },
31 time::Duration,
32};
33use uuid::{Uuid, uuid};
34
35generic_protocol_initializer_setup!(MysteryVibe, "mysteryvibe");
36
37const MYSTERYVIBE_PROTOCOL_UUID: Uuid = uuid!("53bca658-2efe-4388-8ced-333789bac20b");
38
39#[derive(Default)]
40pub struct MysteryVibeInitializer {}
41
42#[async_trait]
43impl ProtocolInitializer for MysteryVibeInitializer {
44 async fn initialize(
45 &mut self,
46 hardware: Arc<Hardware>,
47 def: &ServerDeviceDefinition,
48 ) -> Result<Arc<dyn ProtocolHandler>, ButtplugDeviceError> {
49 let msg = HardwareWriteCmd::new(
50 &[MYSTERYVIBE_PROTOCOL_UUID],
51 Endpoint::TxMode,
52 vec![0x43u8, 0x02u8, 0x00u8],
53 true,
54 );
55 hardware.write_value(&msg).await?;
56 let vibrator_count = def
57 .features()
58 .iter()
59 .filter(|x| x.output().is_some())
60 .count();
61 Ok(Arc::new(MysteryVibe::new(vibrator_count as u8)))
62 }
63}
64
65// Time between Mysteryvibe update commands, in milliseconds. This is basically
66// a best guess derived from watching packet timing a few years ago.
67//
68// Thelemic vibrator. Neat.
69//
70const MYSTERYVIBE_COMMAND_DELAY_MS: u64 = 93;
71
72#[derive(Default)]
73pub struct MysteryVibe {
74 speeds: Vec<AtomicU8>,
75}
76
77impl MysteryVibe {
78 pub fn new(vibrator_count: u8) -> Self {
79 Self {
80 speeds: std::iter::repeat_with(AtomicU8::default)
81 .take(vibrator_count as usize)
82 .collect(),
83 }
84 }
85}
86
87impl ProtocolHandler for MysteryVibe {
88 fn keepalive_strategy(&self) -> ProtocolKeepaliveStrategy {
89 ProtocolKeepaliveStrategy::RepeatLastPacketStrategyWithTiming(Duration::from_millis(
90 MYSTERYVIBE_COMMAND_DELAY_MS,
91 ))
92 }
93
94 fn handle_output_vibrate_cmd(
95 &self,
96 feature_index: u32,
97 _feature_id: Uuid,
98 speed: u32,
99 ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
100 self.speeds[feature_index as usize].store(speed as u8, Ordering::Relaxed);
101 Ok(vec![
102 HardwareWriteCmd::new(
103 &[MYSTERYVIBE_PROTOCOL_UUID],
104 Endpoint::TxVibrate,
105 self
106 .speeds
107 .iter()
108 .map(|x| x.load(Ordering::Relaxed))
109 .collect(),
110 false,
111 )
112 .into(),
113 ])
114 }
115}