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 crate::device::{
9 hardware::{HardwareCommand, HardwareWriteCmd},
10 protocol::{ProtocolHandler, ProtocolKeepaliveStrategy, generic_protocol_setup},
11};
12use buttplug_core::errors::ButtplugDeviceError;
13use buttplug_server_device_config::Endpoint;
14use std::time::Duration;
15use uuid::Uuid;
16
17generic_protocol_setup!(MizzZeeV3, "mizzzee-v3");
18
19// Time between MizzZee v3 update commands, in milliseconds.
20const MIZZZEE3_COMMAND_DELAY_MS: u64 = 200;
21
22fn handle_scale(scale: f32) -> f32 {
23 if scale == 0.0 {
24 return 0.0;
25 }
26 scale * 0.7 + 0.3
27}
28
29fn scalar_to_vector(scalar: u32) -> Vec<u8> {
30 if scalar == 0 {
31 return vec![
32 0x03, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
33 0x00, 0x00, 0x00, 0x00, 0x00,
34 ];
35 }
36
37 const HEADER: [u8; 3] = [0x03, 0x12, 0xf3];
38 const FILL_VEC: [u8; 6] = [0x00, 0xfc, 0x00, 0xfe, 0x40, 0x01];
39
40 let scale: f32 = handle_scale(scalar as f32 / 1000.0) * 1023.0;
41 let modded_scale: u16 = ((scale as u16) << 6) | 60;
42
43 let bytes = modded_scale.to_le_bytes();
44
45 let mut data: Vec<u8> = Vec::new();
46 data.extend_from_slice(&HEADER);
47 data.extend_from_slice(&FILL_VEC);
48 data.extend_from_slice(&bytes);
49 data.extend_from_slice(&FILL_VEC);
50 data.extend_from_slice(&bytes);
51 data.push(0x00);
52
53 data
54}
55
56#[derive(Default)]
57pub struct MizzZeeV3 {}
58
59impl ProtocolHandler for MizzZeeV3 {
60 fn keepalive_strategy(&self) -> ProtocolKeepaliveStrategy {
61 ProtocolKeepaliveStrategy::RepeatLastPacketStrategyWithTiming(Duration::from_millis(
62 MIZZZEE3_COMMAND_DELAY_MS,
63 ))
64 }
65
66 fn handle_output_vibrate_cmd(
67 &self,
68 _feature_index: u32,
69 feature_id: Uuid,
70 speed: u32,
71 ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
72 Ok(vec![
73 HardwareWriteCmd::new(&[feature_id], Endpoint::Tx, scalar_to_vector(speed), true).into(),
74 ])
75 }
76}