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
8// Buttplug Rust Source Code File - See https://buttplug.io for more info.
9//
10// Copyright 2016-2024 Nonpolynomial Labs LLC. All rights reserved.
11//
12// Licensed under the BSD 3-Clause license. See LICENSE file in the project root
13// for full license information.
14
15use uuid::Uuid;
16
17use crate::device::{
18 hardware::{HardwareCommand, HardwareWriteCmd},
19 protocol::{ProtocolHandler, generic_protocol_setup},
20};
21use buttplug_core::errors::ButtplugDeviceError;
22use buttplug_server_device_config::Endpoint;
23
24generic_protocol_setup!(Motorbunny, "motorbunny");
25
26#[derive(Default)]
27pub struct Motorbunny {}
28
29impl ProtocolHandler for Motorbunny {
30 fn handle_output_vibrate_cmd(
31 &self,
32 _feature_index: u32,
33 feature_id: Uuid,
34 speed: u32,
35 ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
36 let mut command_vec: Vec<u8>;
37 if speed == 0 {
38 command_vec = vec![0xf0, 0x00, 0x00, 0x00, 0x00, 0xec];
39 } else {
40 command_vec = vec![0xff];
41 let mut vibe_commands = [speed as u8, 0x14].repeat(7);
42 let crc = vibe_commands
43 .iter()
44 .fold(0u8, |a, b| a.overflowing_add(*b).0);
45 command_vec.append(&mut vibe_commands);
46 command_vec.append(&mut vec![crc, 0xec]);
47 }
48 Ok(vec![
49 HardwareWriteCmd::new(&[feature_id], Endpoint::Tx, command_vec, false).into(),
50 ])
51 }
52
53 fn handle_output_rotate_cmd(
54 &self,
55 _feature_index: u32,
56 feature_id: Uuid,
57 speed: i32,
58 ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
59 let mut command_vec: Vec<u8>;
60 if speed == 0 {
61 command_vec = vec![0xa0, 0x00, 0x00, 0x00, 0x00, 0xec];
62 } else {
63 command_vec = vec![0xaf];
64 let mut rotate_command = [
65 if speed >= 0 { 0x2a } else { 0x29 },
66 speed.unsigned_abs() as u8,
67 ]
68 .repeat(7);
69 let crc = rotate_command
70 .iter()
71 .fold(0u8, |a, b| a.overflowing_add(*b).0);
72 command_vec.append(&mut rotate_command);
73 command_vec.append(&mut vec![crc, 0xec]);
74 }
75 Ok(vec![
76 HardwareWriteCmd::new(&[feature_id], Endpoint::Tx, command_vec, false).into(),
77 ])
78 }
79}