Buttplug sex toy control library

chore: Move protocol implementations to their own module

Divide out from base traits/classes, makes things easier to edit.

+1096 -1092
+524
crates/buttplug_server/src/device/protocol.rs
··· 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 + //! Implementations of communication protocols for hardware supported by Buttplug 9 + 10 + use buttplug_core::{ 11 + errors::ButtplugDeviceError, 12 + message::{Endpoint, InputReadingV4, InputType, OutputCommand}, 13 + }; 14 + use buttplug_server_device_config::{ 15 + DeviceDefinition, 16 + ProtocolCommunicationSpecifier, 17 + UserDeviceIdentifier, 18 + }; 19 + 20 + use crate::{ 21 + device::hardware::{Hardware, HardwareCommand, HardwareReadCmd}, 22 + message::{ 23 + checked_output_cmd::CheckedOutputCmdV4, 24 + spec_enums::ButtplugDeviceCommandMessageUnionV4, 25 + ButtplugServerDeviceMessage, 26 + }, 27 + }; 28 + use async_trait::async_trait; 29 + use futures::{ 30 + future::{self, BoxFuture, FutureExt}, 31 + StreamExt, 32 + }; 33 + use std::sync::Arc; 34 + use std::{pin::Pin, time::Duration}; 35 + use uuid::Uuid; 36 + 37 + /// Strategy for situations where hardware needs to get updates every so often in order to keep 38 + /// things alive. Currently this applies to iOS backgrounding with bluetooth devices, as well as 39 + /// some protocols like Satisfyer and Mysteryvibe that need constant command refreshing, but since 40 + /// we never know which of our hundreds of supported devices someone might connect, we need context 41 + /// as to which keepalive strategy to use. 42 + /// 43 + /// When choosing a keepalive strategy for a protocol: 44 + /// 45 + /// - If the protocol has a command that essentially does nothing to the actuators, set up 46 + /// RepeatPacketStrategy to use that. This is useful for devices that have info commands (like 47 + /// Lovense), ping commands (like The Handy), sensor commands that aren't yet subscribed to output 48 + /// notifications, etc... 49 + /// - If a protocol needs specific timing or keepalives, regardless of the OS/hardware manager being 50 + /// used, like Satisfyer or Mysteryvibe, use RepeatLastPacketStrategyWithTiming. 51 + /// - For many devices with only scalar actuators, RepeatLastPacketStrategy should work. You just 52 + /// need to make sure the protocol doesn't have a packet counter or something else that will trip 53 + /// if the same packet is replayed multiple times. 54 + #[derive(Debug)] 55 + pub enum ProtocolKeepaliveStrategy { 56 + /// Repeat a specific packet, such as a ping or a no-op. Only do this when the hardware manager 57 + /// requires it (currently only iOS bluetooth during backgrounding). 58 + HardwareRequiredRepeatPacketStrategy(HardwareWriteCmd), 59 + /// Repeat whatever the last packet sent was, and send Stop commands until first packet sent. Uses 60 + /// a default timing, suitable for most protocols that don't need constant device updates outside 61 + /// of OS requirements. Only do this when the hardware manager requires it (currently only iOS 62 + /// bluetooth during backgrounding). 63 + HardwareRequiredRepeatLastPacketStrategy, 64 + /// Repeat whatever the last packet sent was, and send Stop commands until first packet sent. Do 65 + /// this regardless of whether or not the hardware manager requires it. Useful for hardware that 66 + /// requires keepalives, like Satisfyer, Mysteryvibe, Leten, etc... 67 + RepeatLastPacketStrategyWithTiming(Duration), 68 + } 69 + 70 + pub trait ProtocolIdentifierFactory: Send + Sync { 71 + fn identifier(&self) -> &str; 72 + fn create(&self) -> Box<dyn ProtocolIdentifier>; 73 + } 74 + 75 + pub enum ProtocolValueCommandPrefilterStrategy { 76 + /// Drop repeated ValueCmd/ValueWithParameterCmd messages 77 + DropRepeats, 78 + /// No filter, send all value messages for processing 79 + None, 80 + } 81 + 82 + fn print_type_of<T>(_: &T) -> &'static str { 83 + std::any::type_name::<T>() 84 + } 85 + 86 + pub struct ProtocolSpecializer { 87 + specifiers: Vec<ProtocolCommunicationSpecifier>, 88 + identifier: Box<dyn ProtocolIdentifier>, 89 + } 90 + 91 + impl ProtocolSpecializer { 92 + pub fn new( 93 + specifiers: Vec<ProtocolCommunicationSpecifier>, 94 + identifier: Box<dyn ProtocolIdentifier>, 95 + ) -> Self { 96 + Self { 97 + specifiers, 98 + identifier, 99 + } 100 + } 101 + 102 + pub fn specifiers(&self) -> &Vec<ProtocolCommunicationSpecifier> { 103 + &self.specifiers 104 + } 105 + 106 + pub fn identify(self) -> Box<dyn ProtocolIdentifier> { 107 + self.identifier 108 + } 109 + } 110 + 111 + #[async_trait] 112 + pub trait ProtocolIdentifier: Sync + Send { 113 + async fn identify( 114 + &mut self, 115 + hardware: Arc<Hardware>, 116 + specifier: ProtocolCommunicationSpecifier, 117 + ) -> Result<(UserDeviceIdentifier, Box<dyn ProtocolInitializer>), ButtplugDeviceError>; 118 + } 119 + 120 + #[async_trait] 121 + pub trait ProtocolInitializer: Sync + Send { 122 + async fn initialize( 123 + &mut self, 124 + hardware: Arc<Hardware>, 125 + device_definition: &DeviceDefinition, 126 + ) -> Result<Arc<dyn ProtocolHandler>, ButtplugDeviceError>; 127 + } 128 + 129 + pub struct GenericProtocolIdentifier { 130 + handler: Option<Arc<dyn ProtocolHandler>>, 131 + protocol_identifier: String, 132 + } 133 + 134 + impl GenericProtocolIdentifier { 135 + pub fn new(handler: Arc<dyn ProtocolHandler>, protocol_identifier: &str) -> Self { 136 + Self { 137 + handler: Some(handler), 138 + protocol_identifier: protocol_identifier.to_owned(), 139 + } 140 + } 141 + } 142 + 143 + #[async_trait] 144 + impl ProtocolIdentifier for GenericProtocolIdentifier { 145 + async fn identify( 146 + &mut self, 147 + hardware: Arc<Hardware>, 148 + _: ProtocolCommunicationSpecifier, 149 + ) -> Result<(UserDeviceIdentifier, Box<dyn ProtocolInitializer>), ButtplugDeviceError> { 150 + let device_identifier = UserDeviceIdentifier::new( 151 + hardware.address(), 152 + &self.protocol_identifier, 153 + &Some(hardware.name().to_owned()), 154 + ); 155 + Ok(( 156 + device_identifier, 157 + Box::new(GenericProtocolInitializer::new( 158 + self.handler.take().unwrap(), 159 + )), 160 + )) 161 + } 162 + } 163 + 164 + pub struct GenericProtocolInitializer { 165 + handler: Option<Arc<dyn ProtocolHandler>>, 166 + } 167 + 168 + impl GenericProtocolInitializer { 169 + pub fn new(handler: Arc<dyn ProtocolHandler>) -> Self { 170 + Self { 171 + handler: Some(handler), 172 + } 173 + } 174 + } 175 + 176 + #[async_trait] 177 + impl ProtocolInitializer for GenericProtocolInitializer { 178 + async fn initialize( 179 + &mut self, 180 + _: Arc<Hardware>, 181 + _: &DeviceDefinition, 182 + ) -> Result<Arc<dyn ProtocolHandler>, ButtplugDeviceError> { 183 + Ok(self.handler.take().unwrap()) 184 + } 185 + } 186 + 187 + pub trait ProtocolHandler: Sync + Send { 188 + fn keepalive_strategy(&self) -> ProtocolKeepaliveStrategy { 189 + ProtocolKeepaliveStrategy::HardwareRequiredRepeatLastPacketStrategy 190 + } 191 + 192 + fn handle_message( 193 + &self, 194 + message: &ButtplugDeviceCommandMessageUnionV4, 195 + ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 196 + self.command_unimplemented(print_type_of(&message)) 197 + } 198 + 199 + // Allow here since this changes between debug/release 200 + #[allow(unused_variables)] 201 + fn command_unimplemented( 202 + &self, 203 + command: &str, 204 + ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 205 + #[cfg(debug_assertions)] 206 + unimplemented!("Command not implemented for this protocol"); 207 + #[cfg(not(debug_assertions))] 208 + Err(ButtplugDeviceError::UnhandledCommand(format!( 209 + "Command not implemented for this protocol: {}", 210 + command 211 + ))) 212 + } 213 + 214 + // The default scalar handler assumes that most devices require discrete commands per feature. If 215 + // a protocol has commands that combine multiple features, either with matched or unmatched 216 + // actuators, they should just implement their own version of this method. 217 + fn handle_output_cmd( 218 + &self, 219 + cmd: &CheckedOutputCmdV4, 220 + ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 221 + let output_command = cmd.output_command(); 222 + match output_command { 223 + OutputCommand::Constrict(x) => { 224 + self.handle_output_constrict_cmd(cmd.feature_index(), cmd.feature_id(), x.value()) 225 + } 226 + OutputCommand::Inflate(x) => { 227 + self.handle_output_inflate_cmd(cmd.feature_index(), cmd.feature_id(), x.value()) 228 + } 229 + OutputCommand::Oscillate(x) => { 230 + self.handle_output_oscillate_cmd(cmd.feature_index(), cmd.feature_id(), x.value()) 231 + } 232 + OutputCommand::Rotate(x) => { 233 + self.handle_output_rotate_cmd(cmd.feature_index(), cmd.feature_id(), x.value()) 234 + } 235 + OutputCommand::Vibrate(x) => { 236 + self.handle_output_vibrate_cmd(cmd.feature_index(), cmd.feature_id(), x.value()) 237 + } 238 + OutputCommand::Position(x) => { 239 + self.handle_output_position_cmd(cmd.feature_index(), cmd.feature_id(), x.value()) 240 + } 241 + OutputCommand::Heater(x) => { 242 + self.handle_output_heater_cmd(cmd.feature_index(), cmd.feature_id(), x.value()) 243 + } 244 + OutputCommand::Led(x) => { 245 + self.handle_output_led_cmd(cmd.feature_index(), cmd.feature_id(), x.value()) 246 + } 247 + OutputCommand::PositionWithDuration(x) => self.handle_position_with_duration_cmd( 248 + cmd.feature_index(), 249 + cmd.feature_id(), 250 + x.position(), 251 + x.duration(), 252 + ), 253 + OutputCommand::RotateWithDirection(x) => self.handle_rotation_with_direction_cmd( 254 + cmd.feature_index(), 255 + cmd.feature_id(), 256 + x.speed(), 257 + x.clockwise(), 258 + ), 259 + } 260 + } 261 + 262 + fn handle_output_vibrate_cmd( 263 + &self, 264 + _feature_index: u32, 265 + _feature_id: Uuid, 266 + _speed: u32, 267 + ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 268 + self.command_unimplemented("OutputCmd (Vibrate Actuator)") 269 + } 270 + 271 + fn handle_output_rotate_cmd( 272 + &self, 273 + _feature_index: u32, 274 + _feature_id: Uuid, 275 + _speed: u32, 276 + ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 277 + self.command_unimplemented("OutputCmd (Rotate Actuator)") 278 + } 279 + 280 + fn handle_output_oscillate_cmd( 281 + &self, 282 + _feature_index: u32, 283 + _feature_id: Uuid, 284 + _speed: u32, 285 + ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 286 + self.command_unimplemented("OutputCmd (Oscillate Actuator)") 287 + } 288 + 289 + fn handle_output_inflate_cmd( 290 + &self, 291 + _feature_index: u32, 292 + _feature_id: Uuid, 293 + _level: u32, 294 + ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 295 + self.command_unimplemented("OutputCmd (Inflate Actuator)") 296 + } 297 + 298 + fn handle_output_constrict_cmd( 299 + &self, 300 + _feature_index: u32, 301 + _feature_id: Uuid, 302 + _level: u32, 303 + ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 304 + self.command_unimplemented("OutputCmd (Constrict Actuator)") 305 + } 306 + 307 + fn handle_output_heater_cmd( 308 + &self, 309 + _feature_index: u32, 310 + _feature_id: Uuid, 311 + _level: u32, 312 + ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 313 + self.command_unimplemented("OutputCmd (Heater Actuator)") 314 + } 315 + 316 + fn handle_output_led_cmd( 317 + &self, 318 + _feature_index: u32, 319 + _feature_id: Uuid, 320 + _level: u32, 321 + ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 322 + self.command_unimplemented("OutputCmd (Led Actuator)") 323 + } 324 + 325 + fn handle_output_position_cmd( 326 + &self, 327 + _feature_index: u32, 328 + _feature_id: Uuid, 329 + _position: u32, 330 + ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 331 + self.command_unimplemented("OutputCmd (Position Actuator)") 332 + } 333 + 334 + fn handle_position_with_duration_cmd( 335 + &self, 336 + _feature_index: u32, 337 + _feature_id: Uuid, 338 + _position: u32, 339 + _duration: u32, 340 + ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 341 + self.command_unimplemented("OutputCmd (Position w/ Duration Actuator)") 342 + } 343 + 344 + fn handle_rotation_with_direction_cmd( 345 + &self, 346 + _feature_index: u32, 347 + _feature_id: Uuid, 348 + _speed: u32, 349 + _clockwise: bool, 350 + ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 351 + self.command_unimplemented("OutputCmd (Rotation w/ Direction Actuator)") 352 + } 353 + 354 + fn handle_input_subscribe_cmd( 355 + &self, 356 + _device_index: u32, 357 + _device: Arc<Hardware>, 358 + _feature_index: u32, 359 + _feature_id: Uuid, 360 + _sensor_type: InputType, 361 + ) -> BoxFuture<Result<(), ButtplugDeviceError>> { 362 + future::ready(Err(ButtplugDeviceError::UnhandledCommand( 363 + "Command not implemented for this protocol: InputCmd (Subscribe)".to_string(), 364 + ))) 365 + .boxed() 366 + } 367 + 368 + fn handle_input_unsubscribe_cmd( 369 + &self, 370 + _device: Arc<Hardware>, 371 + _feature_index: u32, 372 + _feature_id: Uuid, 373 + _sensor_type: InputType, 374 + ) -> BoxFuture<Result<(), ButtplugDeviceError>> { 375 + future::ready(Err(ButtplugDeviceError::UnhandledCommand( 376 + "Command not implemented for this protocol: InputCmd (Unsubscribe)".to_string(), 377 + ))) 378 + .boxed() 379 + } 380 + 381 + fn handle_input_read_cmd( 382 + &self, 383 + device_index: u32, 384 + device: Arc<Hardware>, 385 + feature_index: u32, 386 + feature_id: Uuid, 387 + sensor_type: InputType, 388 + ) -> BoxFuture<Result<InputReadingV4, ButtplugDeviceError>> { 389 + match sensor_type { 390 + InputType::Battery => { 391 + self.handle_battery_level_cmd(device_index, device, feature_index, feature_id) 392 + } 393 + _ => future::ready(Err(ButtplugDeviceError::UnhandledCommand( 394 + "Command not implemented for this protocol: InputCmd (Read)".to_string(), 395 + ))) 396 + .boxed(), 397 + } 398 + } 399 + 400 + // Handle Battery Level returns a SensorReading, as we'll always need to do a sensor index 401 + // conversion on it. 402 + fn handle_battery_level_cmd( 403 + &self, 404 + device_index: u32, 405 + device: Arc<Hardware>, 406 + feature_index: u32, 407 + feature_id: Uuid, 408 + ) -> BoxFuture<Result<InputReadingV4, ButtplugDeviceError>> { 409 + // If we have a standardized BLE Battery endpoint, handle that above the 410 + // protocol, as it'll always be the same. 411 + if device.endpoints().contains(&Endpoint::RxBLEBattery) { 412 + debug!("Trying to get battery reading."); 413 + let msg = HardwareReadCmd::new(feature_id, Endpoint::RxBLEBattery, 1, 0); 414 + let fut = device.read_value(&msg); 415 + async move { 416 + let hw_msg = fut.await?; 417 + let battery_level = hw_msg.data()[0] as i32; 418 + let battery_reading = InputReadingV4::new( 419 + device_index, 420 + feature_index, 421 + InputType::Battery, 422 + vec![battery_level], 423 + ); 424 + debug!("Got battery reading: {}", battery_level); 425 + Ok(battery_reading) 426 + } 427 + .boxed() 428 + } else { 429 + future::ready(Err(ButtplugDeviceError::UnhandledCommand( 430 + "Command not implemented for this protocol: SensorReadCmd".to_string(), 431 + ))) 432 + .boxed() 433 + } 434 + } 435 + 436 + fn handle_rssi_level_cmd( 437 + &self, 438 + _device: Arc<Hardware>, 439 + _feature_index: u32, 440 + _feature_id: Uuid, 441 + ) -> BoxFuture<Result<(), ButtplugDeviceError>> { 442 + future::ready(Err(ButtplugDeviceError::UnhandledCommand( 443 + "Command not implemented for this protocol: SensorReadCmd".to_string(), 444 + ))) 445 + .boxed() 446 + } 447 + 448 + fn event_stream( 449 + &self, 450 + ) -> Pin<Box<dyn tokio_stream::Stream<Item = ButtplugServerDeviceMessage> + Send>> { 451 + tokio_stream::empty().boxed() 452 + } 453 + } 454 + 455 + #[macro_export] 456 + macro_rules! generic_protocol_setup { 457 + ( $protocol_name:ident, $protocol_identifier:tt) => { 458 + paste::paste! { 459 + pub mod setup { 460 + use std::sync::Arc; 461 + use $crate::device::protocol::{ 462 + GenericProtocolIdentifier, ProtocolIdentifier, ProtocolIdentifierFactory, 463 + }; 464 + #[derive(Default)] 465 + pub struct [< $protocol_name IdentifierFactory >] {} 466 + 467 + impl ProtocolIdentifierFactory for [< $protocol_name IdentifierFactory >] { 468 + fn identifier(&self) -> &str { 469 + $protocol_identifier 470 + } 471 + 472 + fn create(&self) -> Box<dyn ProtocolIdentifier> { 473 + Box::new(GenericProtocolIdentifier::new( 474 + Arc::new(super::$protocol_name::default()), 475 + self.identifier(), 476 + )) 477 + } 478 + } 479 + } 480 + } 481 + }; 482 + } 483 + 484 + #[macro_export] 485 + macro_rules! generic_protocol_initializer_setup { 486 + ( $protocol_name:ident, $protocol_identifier:tt) => { 487 + paste::paste! { 488 + pub mod setup { 489 + use $crate::device::protocol::{ProtocolIdentifier, ProtocolIdentifierFactory}; 490 + #[derive(Default)] 491 + pub struct [< $protocol_name IdentifierFactory >] {} 492 + 493 + impl ProtocolIdentifierFactory for [< $protocol_name IdentifierFactory >] { 494 + fn identifier(&self) -> &str { 495 + $protocol_identifier 496 + } 497 + 498 + fn create(&self) -> Box<dyn ProtocolIdentifier> { 499 + Box::new(super::[< $protocol_name Identifier >]::default()) 500 + } 501 + } 502 + } 503 + 504 + #[derive(Default)] 505 + pub struct [< $protocol_name Identifier >] {} 506 + 507 + #[async_trait] 508 + impl ProtocolIdentifier for [< $protocol_name Identifier >] { 509 + async fn identify( 510 + &mut self, 511 + hardware: Arc<Hardware>, 512 + _: ProtocolCommunicationSpecifier, 513 + ) -> Result<(UserDeviceIdentifier, Box<dyn ProtocolInitializer>), ButtplugDeviceError> { 514 + Ok((UserDeviceIdentifier::new(hardware.address(), $protocol_identifier, &Some(hardware.name().to_owned())), Box::new([< $protocol_name Initializer >]::default()))) 515 + } 516 + } 517 + } 518 + }; 519 + } 520 + 521 + pub use generic_protocol_initializer_setup; 522 + pub use generic_protocol_setup; 523 + 524 + use super::hardware::HardwareWriteCmd;
crates/buttplug_server/src/device/protocol/activejoy.rs crates/buttplug_server/src/device/protocol_impl/activejoy.rs
crates/buttplug_server/src/device/protocol/adrienlastic.rs crates/buttplug_server/src/device/protocol_impl/adrienlastic.rs
crates/buttplug_server/src/device/protocol/amorelie_joy.rs crates/buttplug_server/src/device/protocol_impl/amorelie_joy.rs
crates/buttplug_server/src/device/protocol/aneros.rs crates/buttplug_server/src/device/protocol_impl/aneros.rs
crates/buttplug_server/src/device/protocol/ankni.rs crates/buttplug_server/src/device/protocol_impl/ankni.rs
crates/buttplug_server/src/device/protocol/bananasome.rs crates/buttplug_server/src/device/protocol_impl/bananasome.rs
crates/buttplug_server/src/device/protocol/cachito.rs crates/buttplug_server/src/device/protocol_impl/cachito.rs
crates/buttplug_server/src/device/protocol/cowgirl.rs crates/buttplug_server/src/device/protocol_impl/cowgirl.rs
crates/buttplug_server/src/device/protocol/cowgirl_cone.rs crates/buttplug_server/src/device/protocol_impl/cowgirl_cone.rs
crates/buttplug_server/src/device/protocol/cupido.rs crates/buttplug_server/src/device/protocol_impl/cupido.rs
crates/buttplug_server/src/device/protocol/deepsire.rs crates/buttplug_server/src/device/protocol_impl/deepsire.rs
crates/buttplug_server/src/device/protocol/feelingso.rs crates/buttplug_server/src/device/protocol_impl/feelingso.rs
crates/buttplug_server/src/device/protocol/fleshlight_launch_helper.rs crates/buttplug_server/src/device/protocol_impl/fleshlight_launch_helper.rs
crates/buttplug_server/src/device/protocol/fleshy_thrust.rs crates/buttplug_server/src/device/protocol_impl/fleshy_thrust.rs
crates/buttplug_server/src/device/protocol/foreo.rs crates/buttplug_server/src/device/protocol_impl/foreo.rs
crates/buttplug_server/src/device/protocol/fox.rs crates/buttplug_server/src/device/protocol_impl/fox.rs
crates/buttplug_server/src/device/protocol/fredorch.rs crates/buttplug_server/src/device/protocol_impl/fredorch.rs
crates/buttplug_server/src/device/protocol/fredorch_rotary.rs crates/buttplug_server/src/device/protocol_impl/fredorch_rotary.rs
crates/buttplug_server/src/device/protocol/galaku.rs crates/buttplug_server/src/device/protocol_impl/galaku.rs
crates/buttplug_server/src/device/protocol/galaku_pump.rs crates/buttplug_server/src/device/protocol_impl/galaku_pump.rs
crates/buttplug_server/src/device/protocol/hgod.rs crates/buttplug_server/src/device/protocol_impl/hgod.rs
crates/buttplug_server/src/device/protocol/hismith.rs crates/buttplug_server/src/device/protocol_impl/hismith.rs
crates/buttplug_server/src/device/protocol/hismith_mini.rs crates/buttplug_server/src/device/protocol_impl/hismith_mini.rs
crates/buttplug_server/src/device/protocol/htk_bm.rs crates/buttplug_server/src/device/protocol_impl/htk_bm.rs
crates/buttplug_server/src/device/protocol/itoys.rs crates/buttplug_server/src/device/protocol_impl/itoys.rs
crates/buttplug_server/src/device/protocol/jejoue.rs crates/buttplug_server/src/device/protocol_impl/jejoue.rs
crates/buttplug_server/src/device/protocol/joyhub.rs crates/buttplug_server/src/device/protocol_impl/joyhub.rs
crates/buttplug_server/src/device/protocol/joyhub_v2.rs crates/buttplug_server/src/device/protocol_impl/joyhub_v2.rs
crates/buttplug_server/src/device/protocol/joyhub_v3.rs crates/buttplug_server/src/device/protocol_impl/joyhub_v3.rs
crates/buttplug_server/src/device/protocol/joyhub_v4.rs crates/buttplug_server/src/device/protocol_impl/joyhub_v4.rs
crates/buttplug_server/src/device/protocol/joyhub_v5.rs crates/buttplug_server/src/device/protocol_impl/joyhub_v5.rs
crates/buttplug_server/src/device/protocol/joyhub_v6.rs crates/buttplug_server/src/device/protocol_impl/joyhub_v6.rs
crates/buttplug_server/src/device/protocol/kgoal_boost.rs crates/buttplug_server/src/device/protocol_impl/kgoal_boost.rs
crates/buttplug_server/src/device/protocol/kiiroo_prowand.rs crates/buttplug_server/src/device/protocol_impl/kiiroo_prowand.rs
crates/buttplug_server/src/device/protocol/kiiroo_spot.rs crates/buttplug_server/src/device/protocol_impl/kiiroo_spot.rs
crates/buttplug_server/src/device/protocol/kiiroo_v2.rs crates/buttplug_server/src/device/protocol_impl/kiiroo_v2.rs
crates/buttplug_server/src/device/protocol/kiiroo_v21.rs crates/buttplug_server/src/device/protocol_impl/kiiroo_v21.rs
crates/buttplug_server/src/device/protocol/kiiroo_v21_initialized.rs crates/buttplug_server/src/device/protocol_impl/kiiroo_v21_initialized.rs
crates/buttplug_server/src/device/protocol/kiiroo_v2_vibrator.rs crates/buttplug_server/src/device/protocol_impl/kiiroo_v2_vibrator.rs
crates/buttplug_server/src/device/protocol/kizuna.rs crates/buttplug_server/src/device/protocol_impl/kizuna.rs
crates/buttplug_server/src/device/protocol/lelo_harmony.rs crates/buttplug_server/src/device/protocol_impl/lelo_harmony.rs
crates/buttplug_server/src/device/protocol/lelof1s.rs crates/buttplug_server/src/device/protocol_impl/lelof1s.rs
crates/buttplug_server/src/device/protocol/lelof1sv2.rs crates/buttplug_server/src/device/protocol_impl/lelof1sv2.rs
crates/buttplug_server/src/device/protocol/leten.rs crates/buttplug_server/src/device/protocol_impl/leten.rs
crates/buttplug_server/src/device/protocol/libo_elle.rs crates/buttplug_server/src/device/protocol_impl/libo_elle.rs
crates/buttplug_server/src/device/protocol/libo_shark.rs crates/buttplug_server/src/device/protocol_impl/libo_shark.rs
crates/buttplug_server/src/device/protocol/libo_vibes.rs crates/buttplug_server/src/device/protocol_impl/libo_vibes.rs
crates/buttplug_server/src/device/protocol/lioness.rs crates/buttplug_server/src/device/protocol_impl/lioness.rs
crates/buttplug_server/src/device/protocol/loob.rs crates/buttplug_server/src/device/protocol_impl/loob.rs
crates/buttplug_server/src/device/protocol/lovedistance.rs crates/buttplug_server/src/device/protocol_impl/lovedistance.rs
crates/buttplug_server/src/device/protocol/lovehoney_desire.rs crates/buttplug_server/src/device/protocol_impl/lovehoney_desire.rs
crates/buttplug_server/src/device/protocol/lovense/lovense_max.rs crates/buttplug_server/src/device/protocol_impl/lovense/lovense_max.rs
crates/buttplug_server/src/device/protocol/lovense/lovense_multi_actuator.rs crates/buttplug_server/src/device/protocol_impl/lovense/lovense_multi_actuator.rs
crates/buttplug_server/src/device/protocol/lovense/lovense_rotate_vibrator.rs crates/buttplug_server/src/device/protocol_impl/lovense/lovense_rotate_vibrator.rs
crates/buttplug_server/src/device/protocol/lovense/lovense_single_actuator.rs crates/buttplug_server/src/device/protocol_impl/lovense/lovense_single_actuator.rs
crates/buttplug_server/src/device/protocol/lovense/lovense_stroker.rs crates/buttplug_server/src/device/protocol_impl/lovense/lovense_stroker.rs
crates/buttplug_server/src/device/protocol/lovense/mod.rs crates/buttplug_server/src/device/protocol_impl/lovense/mod.rs
crates/buttplug_server/src/device/protocol/lovense_connect_service.rs crates/buttplug_server/src/device/protocol_impl/lovense_connect_service.rs
crates/buttplug_server/src/device/protocol/lovenuts.rs crates/buttplug_server/src/device/protocol_impl/lovenuts.rs
crates/buttplug_server/src/device/protocol/luvmazer.rs crates/buttplug_server/src/device/protocol_impl/luvmazer.rs
crates/buttplug_server/src/device/protocol/magic_motion_v1.rs crates/buttplug_server/src/device/protocol_impl/magic_motion_v1.rs
crates/buttplug_server/src/device/protocol/magic_motion_v2.rs crates/buttplug_server/src/device/protocol_impl/magic_motion_v2.rs
crates/buttplug_server/src/device/protocol/magic_motion_v3.rs crates/buttplug_server/src/device/protocol_impl/magic_motion_v3.rs
crates/buttplug_server/src/device/protocol/magic_motion_v4.rs crates/buttplug_server/src/device/protocol_impl/magic_motion_v4.rs
crates/buttplug_server/src/device/protocol/mannuo.rs crates/buttplug_server/src/device/protocol_impl/mannuo.rs
crates/buttplug_server/src/device/protocol/maxpro.rs crates/buttplug_server/src/device/protocol_impl/maxpro.rs
crates/buttplug_server/src/device/protocol/meese.rs crates/buttplug_server/src/device/protocol_impl/meese.rs
crates/buttplug_server/src/device/protocol/metaxsire.rs crates/buttplug_server/src/device/protocol_impl/metaxsire.rs
crates/buttplug_server/src/device/protocol/metaxsire_v2.rs crates/buttplug_server/src/device/protocol_impl/metaxsire_v2.rs
crates/buttplug_server/src/device/protocol/metaxsire_v3.rs crates/buttplug_server/src/device/protocol_impl/metaxsire_v3.rs
crates/buttplug_server/src/device/protocol/metaxsire_v4.rs crates/buttplug_server/src/device/protocol_impl/metaxsire_v4.rs
crates/buttplug_server/src/device/protocol/mizzzee.rs crates/buttplug_server/src/device/protocol_impl/mizzzee.rs
crates/buttplug_server/src/device/protocol/mizzzee_v2.rs crates/buttplug_server/src/device/protocol_impl/mizzzee_v2.rs
crates/buttplug_server/src/device/protocol/mizzzee_v3.rs crates/buttplug_server/src/device/protocol_impl/mizzzee_v3.rs
-1092
crates/buttplug_server/src/device/protocol/mod.rs
··· 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 - //! Implementations of communication protocols for hardware supported by Buttplug 9 - 10 - // Utility mods 11 - pub mod fleshlight_launch_helper; 12 - 13 - // Since users can pick and choose protocols, we need all of these to be public. 14 - pub mod activejoy; 15 - pub mod adrienlastic; 16 - pub mod amorelie_joy; 17 - pub mod aneros; 18 - pub mod ankni; 19 - pub mod bananasome; 20 - pub mod cachito; 21 - pub mod cowgirl; 22 - pub mod cowgirl_cone; 23 - pub mod cupido; 24 - pub mod deepsire; 25 - pub mod feelingso; 26 - pub mod fleshy_thrust; 27 - pub mod foreo; 28 - pub mod fox; 29 - pub mod fredorch; 30 - pub mod fredorch_rotary; 31 - pub mod galaku; 32 - pub mod galaku_pump; 33 - pub mod hgod; 34 - pub mod hismith; 35 - pub mod hismith_mini; 36 - pub mod htk_bm; 37 - pub mod itoys; 38 - pub mod jejoue; 39 - // pub mod joyhub; 40 - // pub mod joyhub_v2; 41 - pub mod joyhub_v3; 42 - // pub mod joyhub_v4; 43 - // pub mod joyhub_v5; 44 - // pub mod joyhub_v6; 45 - pub mod kgoal_boost; 46 - pub mod kiiroo_prowand; 47 - pub mod kiiroo_spot; 48 - pub mod kiiroo_v2; 49 - pub mod kiiroo_v21; 50 - pub mod kiiroo_v21_initialized; 51 - pub mod kiiroo_v2_vibrator; 52 - pub mod kizuna; 53 - pub mod lelo_harmony; 54 - pub mod lelof1s; 55 - pub mod lelof1sv2; 56 - pub mod leten; 57 - pub mod libo_elle; 58 - pub mod libo_shark; 59 - pub mod libo_vibes; 60 - pub mod lioness; 61 - pub mod loob; 62 - pub mod lovedistance; 63 - pub mod lovehoney_desire; 64 - pub mod lovense; 65 - // pub mod lovense_connect_service; 66 - pub mod lovenuts; 67 - pub mod luvmazer; 68 - pub mod magic_motion_v1; 69 - pub mod magic_motion_v2; 70 - pub mod magic_motion_v3; 71 - pub mod magic_motion_v4; 72 - pub mod mannuo; 73 - pub mod maxpro; 74 - pub mod meese; 75 - pub mod metaxsire; 76 - pub mod metaxsire_v2; 77 - pub mod metaxsire_v3; 78 - mod metaxsire_v4; 79 - pub mod mizzzee; 80 - pub mod mizzzee_v2; 81 - pub mod mizzzee_v3; 82 - pub mod monsterpub; 83 - pub mod motorbunny; 84 - pub mod mysteryvibe; 85 - pub mod mysteryvibe_v2; 86 - pub mod nextlevelracing; 87 - pub mod nexus_revo; 88 - pub mod nintendo_joycon; 89 - pub mod nobra; 90 - pub mod omobo; 91 - pub mod patoo; 92 - pub mod picobong; 93 - pub mod pink_punch; 94 - pub mod prettylove; 95 - pub mod raw_protocol; 96 - pub mod realov; 97 - pub mod sakuraneko; 98 - pub mod satisfyer; 99 - pub mod sensee; 100 - pub mod sensee_capsule; 101 - pub mod sensee_v2; 102 - pub mod serveu; 103 - pub mod sexverse_lg389; 104 - pub mod svakom; 105 - pub mod synchro; 106 - pub mod tcode_v03; 107 - pub mod thehandy; 108 - pub mod tryfun; 109 - pub mod tryfun_blackhole; 110 - pub mod tryfun_meta2; 111 - pub mod vibcrafter; 112 - pub mod vibratissimo; 113 - pub mod vorze_sa; 114 - pub mod wetoy; 115 - pub mod wevibe; 116 - pub mod wevibe8bit; 117 - pub mod wevibe_chorus; 118 - pub mod xibao; 119 - pub mod xinput; 120 - pub mod xiuxiuda; 121 - pub mod xuanhuan; 122 - pub mod youcups; 123 - pub mod youou; 124 - pub mod zalo; 125 - 126 - use buttplug_core::{ 127 - errors::ButtplugDeviceError, 128 - message::{Endpoint, InputReadingV4, InputType, OutputCommand}, 129 - }; 130 - use buttplug_server_device_config::{ 131 - DeviceDefinition, 132 - ProtocolCommunicationSpecifier, 133 - UserDeviceIdentifier, 134 - }; 135 - 136 - use crate::{ 137 - device::hardware::{Hardware, HardwareCommand, HardwareReadCmd}, 138 - message::{ 139 - checked_output_cmd::CheckedOutputCmdV4, 140 - spec_enums::ButtplugDeviceCommandMessageUnionV4, 141 - ButtplugServerDeviceMessage, 142 - }, 143 - }; 144 - use async_trait::async_trait; 145 - use futures::{ 146 - future::{self, BoxFuture, FutureExt}, 147 - StreamExt, 148 - }; 149 - use std::{collections::HashMap, sync::Arc}; 150 - use std::{pin::Pin, time::Duration}; 151 - use uuid::Uuid; 152 - 153 - /// Strategy for situations where hardware needs to get updates every so often in order to keep 154 - /// things alive. Currently this applies to iOS backgrounding with bluetooth devices, as well as 155 - /// some protocols like Satisfyer and Mysteryvibe that need constant command refreshing, but since 156 - /// we never know which of our hundreds of supported devices someone might connect, we need context 157 - /// as to which keepalive strategy to use. 158 - /// 159 - /// When choosing a keepalive strategy for a protocol: 160 - /// 161 - /// - If the protocol has a command that essentially does nothing to the actuators, set up 162 - /// RepeatPacketStrategy to use that. This is useful for devices that have info commands (like 163 - /// Lovense), ping commands (like The Handy), sensor commands that aren't yet subscribed to output 164 - /// notifications, etc... 165 - /// - If a protocol needs specific timing or keepalives, regardless of the OS/hardware manager being 166 - /// used, like Satisfyer or Mysteryvibe, use RepeatLastPacketStrategyWithTiming. 167 - /// - For many devices with only scalar actuators, RepeatLastPacketStrategy should work. You just 168 - /// need to make sure the protocol doesn't have a packet counter or something else that will trip 169 - /// if the same packet is replayed multiple times. 170 - #[derive(Debug)] 171 - pub enum ProtocolKeepaliveStrategy { 172 - /// Repeat a specific packet, such as a ping or a no-op. Only do this when the hardware manager 173 - /// requires it (currently only iOS bluetooth during backgrounding). 174 - HardwareRequiredRepeatPacketStrategy(HardwareWriteCmd), 175 - /// Repeat whatever the last packet sent was, and send Stop commands until first packet sent. Uses 176 - /// a default timing, suitable for most protocols that don't need constant device updates outside 177 - /// of OS requirements. Only do this when the hardware manager requires it (currently only iOS 178 - /// bluetooth during backgrounding). 179 - HardwareRequiredRepeatLastPacketStrategy, 180 - /// Repeat whatever the last packet sent was, and send Stop commands until first packet sent. Do 181 - /// this regardless of whether or not the hardware manager requires it. Useful for hardware that 182 - /// requires keepalives, like Satisfyer, Mysteryvibe, Leten, etc... 183 - RepeatLastPacketStrategyWithTiming(Duration), 184 - } 185 - 186 - pub trait ProtocolIdentifierFactory: Send + Sync { 187 - fn identifier(&self) -> &str; 188 - fn create(&self) -> Box<dyn ProtocolIdentifier>; 189 - } 190 - 191 - pub fn get_default_protocol_map() -> HashMap<String, Arc<dyn ProtocolIdentifierFactory>> { 192 - let mut map = HashMap::new(); 193 - fn add_to_protocol_map<T>( 194 - map: &mut HashMap<String, Arc<dyn ProtocolIdentifierFactory>>, 195 - factory: T, 196 - ) where 197 - T: ProtocolIdentifierFactory + 'static, 198 - { 199 - let factory = Arc::new(factory); 200 - map.insert(factory.identifier().to_owned(), factory); 201 - } 202 - 203 - add_to_protocol_map( 204 - &mut map, 205 - activejoy::setup::ActiveJoyIdentifierFactory::default(), 206 - ); 207 - add_to_protocol_map( 208 - &mut map, 209 - adrienlastic::setup::AdrienLasticIdentifierFactory::default(), 210 - ); 211 - add_to_protocol_map( 212 - &mut map, 213 - amorelie_joy::setup::AmorelieJoyIdentifierFactory::default(), 214 - ); 215 - add_to_protocol_map(&mut map, aneros::setup::AnerosIdentifierFactory::default()); 216 - add_to_protocol_map(&mut map, ankni::setup::AnkniIdentifierFactory::default()); 217 - add_to_protocol_map( 218 - &mut map, 219 - bananasome::setup::BananasomeIdentifierFactory::default(), 220 - ); 221 - add_to_protocol_map( 222 - &mut map, 223 - cachito::setup::CachitoIdentifierFactory::default(), 224 - ); 225 - add_to_protocol_map( 226 - &mut map, 227 - cowgirl::setup::CowgirlIdentifierFactory::default(), 228 - ); 229 - add_to_protocol_map( 230 - &mut map, 231 - cowgirl_cone::setup::CowgirlConeIdentifierFactory::default(), 232 - ); 233 - add_to_protocol_map(&mut map, cupido::setup::CupidoIdentifierFactory::default()); 234 - add_to_protocol_map( 235 - &mut map, 236 - deepsire::setup::DeepSireIdentifierFactory::default(), 237 - ); 238 - add_to_protocol_map( 239 - &mut map, 240 - lovense::setup::LovenseIdentifierFactory::default(), 241 - ); 242 - add_to_protocol_map( 243 - &mut map, 244 - hismith::setup::HismithIdentifierFactory::default(), 245 - ); 246 - add_to_protocol_map( 247 - &mut map, 248 - hismith_mini::setup::HismithMiniIdentifierFactory::default(), 249 - ); 250 - add_to_protocol_map(&mut map, htk_bm::setup::HtkBmIdentifierFactory::default()); 251 - add_to_protocol_map( 252 - &mut map, 253 - thehandy::setup::TheHandyIdentifierFactory::default(), 254 - ); 255 - 256 - add_to_protocol_map( 257 - &mut map, 258 - feelingso::setup::FeelingSoIdentifierFactory::default(), 259 - ); 260 - add_to_protocol_map( 261 - &mut map, 262 - fleshy_thrust::setup::FleshyThrustIdentifierFactory::default(), 263 - ); 264 - add_to_protocol_map(&mut map, foreo::setup::ForeoIdentifierFactory::default()); 265 - add_to_protocol_map(&mut map, fox::setup::FoxIdentifierFactory::default()); 266 - add_to_protocol_map( 267 - &mut map, 268 - fredorch::setup::FredorchIdentifierFactory::default(), 269 - ); 270 - add_to_protocol_map( 271 - &mut map, 272 - fredorch_rotary::setup::FredorchRotaryIdentifierFactory::default(), 273 - ); 274 - 275 - add_to_protocol_map(&mut map, hgod::setup::HgodIdentifierFactory::default()); 276 - 277 - add_to_protocol_map( 278 - &mut map, 279 - galaku_pump::setup::GalakuPumpIdentifierFactory::default(), 280 - ); 281 - 282 - add_to_protocol_map(&mut map, galaku::setup::GalakuIdentifierFactory::default()); 283 - 284 - add_to_protocol_map(&mut map, itoys::setup::IToysIdentifierFactory::default()); 285 - add_to_protocol_map(&mut map, jejoue::setup::JeJoueIdentifierFactory::default()); 286 - // add_to_protocol_map(&mut map, joyhub::setup::JoyHubIdentifierFactory::default()); 287 - // add_to_protocol_map( 288 - // &mut map, 289 - // joyhub_v2::setup::JoyHubV2IdentifierFactory::default(), 290 - // ); 291 - 292 - add_to_protocol_map( 293 - &mut map, 294 - joyhub_v3::setup::JoyHubV3IdentifierFactory::default(), 295 - ); 296 - 297 - // add_to_protocol_map( 298 - // &mut map, 299 - // joyhub_v4::setup::JoyHubV4IdentifierFactory::default(), 300 - // ); 301 - // add_to_protocol_map( 302 - // &mut map, 303 - // joyhub_v5::setup::JoyHubV5IdentifierFactory::default(), 304 - // ); 305 - // add_to_protocol_map( 306 - // &mut map, 307 - // joyhub_v6::setup::JoyHubV6IdentifierFactory::default(), 308 - // ); 309 - add_to_protocol_map( 310 - &mut map, 311 - kiiroo_prowand::setup::KiirooProWandIdentifierFactory::default(), 312 - ); 313 - add_to_protocol_map( 314 - &mut map, 315 - kiiroo_spot::setup::KiirooSpotIdentifierFactory::default(), 316 - ); 317 - add_to_protocol_map( 318 - &mut map, 319 - kiiroo_v2::setup::KiirooV2IdentifierFactory::default(), 320 - ); 321 - add_to_protocol_map( 322 - &mut map, 323 - kiiroo_v2_vibrator::setup::KiirooV2VibratorIdentifierFactory::default(), 324 - ); 325 - add_to_protocol_map( 326 - &mut map, 327 - kiiroo_v21::setup::KiirooV21IdentifierFactory::default(), 328 - ); 329 - add_to_protocol_map( 330 - &mut map, 331 - kiiroo_v21_initialized::setup::KiirooV21InitializedIdentifierFactory::default(), 332 - ); 333 - add_to_protocol_map(&mut map, kizuna::setup::KizunaIdentifierFactory::default()); 334 - add_to_protocol_map( 335 - &mut map, 336 - lelof1s::setup::LeloF1sIdentifierFactory::default(), 337 - ); 338 - add_to_protocol_map( 339 - &mut map, 340 - lelof1sv2::setup::LeloF1sV2IdentifierFactory::default(), 341 - ); 342 - add_to_protocol_map(&mut map, leten::setup::LetenIdentifierFactory::default()); 343 - add_to_protocol_map( 344 - &mut map, 345 - lelo_harmony::setup::LeloHarmonyIdentifierFactory::default(), 346 - ); 347 - add_to_protocol_map( 348 - &mut map, 349 - libo_elle::setup::LiboElleIdentifierFactory::default(), 350 - ); 351 - add_to_protocol_map( 352 - &mut map, 353 - libo_shark::setup::LiboSharkIdentifierFactory::default(), 354 - ); 355 - add_to_protocol_map( 356 - &mut map, 357 - libo_vibes::setup::LiboVibesIdentifierFactory::default(), 358 - ); 359 - add_to_protocol_map( 360 - &mut map, 361 - lioness::setup::LionessIdentifierFactory::default(), 362 - ); 363 - add_to_protocol_map(&mut map, loob::setup::LoobIdentifierFactory::default()); 364 - add_to_protocol_map( 365 - &mut map, 366 - lovehoney_desire::setup::LovehoneyDesireIdentifierFactory::default(), 367 - ); 368 - add_to_protocol_map( 369 - &mut map, 370 - lovedistance::setup::LoveDistanceIdentifierFactory::default(), 371 - ); 372 - // add_to_protocol_map( 373 - // &mut map, 374 - // lovense_connect_service::setup::LovenseConnectServiceIdentifierFactory::default(), 375 - // ); 376 - add_to_protocol_map( 377 - &mut map, 378 - lovenuts::setup::LoveNutsIdentifierFactory::default(), 379 - ); 380 - add_to_protocol_map( 381 - &mut map, 382 - luvmazer::setup::LuvmazerIdentifierFactory::default(), 383 - ); 384 - add_to_protocol_map( 385 - &mut map, 386 - magic_motion_v1::setup::MagicMotionV1IdentifierFactory::default(), 387 - ); 388 - add_to_protocol_map( 389 - &mut map, 390 - magic_motion_v2::setup::MagicMotionV2IdentifierFactory::default(), 391 - ); 392 - add_to_protocol_map( 393 - &mut map, 394 - magic_motion_v3::setup::MagicMotionV3IdentifierFactory::default(), 395 - ); 396 - add_to_protocol_map( 397 - &mut map, 398 - magic_motion_v4::setup::MagicMotionV4IdentifierFactory::default(), 399 - ); 400 - add_to_protocol_map(&mut map, mannuo::setup::ManNuoIdentifierFactory::default()); 401 - add_to_protocol_map(&mut map, maxpro::setup::MaxproIdentifierFactory::default()); 402 - add_to_protocol_map(&mut map, meese::setup::MeeseIdentifierFactory::default()); 403 - add_to_protocol_map( 404 - &mut map, 405 - metaxsire::setup::MetaXSireIdentifierFactory::default(), 406 - ); 407 - add_to_protocol_map( 408 - &mut map, 409 - metaxsire_v2::setup::MetaXSireV2IdentifierFactory::default(), 410 - ); 411 - add_to_protocol_map( 412 - &mut map, 413 - metaxsire_v3::setup::MetaXSireV3IdentifierFactory::default(), 414 - ); 415 - add_to_protocol_map( 416 - &mut map, 417 - metaxsire_v4::setup::MetaXSireV4IdentifierFactory::default(), 418 - ); 419 - add_to_protocol_map( 420 - &mut map, 421 - mizzzee::setup::MizzZeeIdentifierFactory::default(), 422 - ); 423 - add_to_protocol_map( 424 - &mut map, 425 - mizzzee_v2::setup::MizzZeeV2IdentifierFactory::default(), 426 - ); 427 - add_to_protocol_map( 428 - &mut map, 429 - mizzzee_v3::setup::MizzZeeV3IdentifierFactory::default(), 430 - ); 431 - add_to_protocol_map( 432 - &mut map, 433 - monsterpub::setup::MonsterPubIdentifierFactory::default(), 434 - ); 435 - add_to_protocol_map( 436 - &mut map, 437 - motorbunny::setup::MotorbunnyIdentifierFactory::default(), 438 - ); 439 - add_to_protocol_map( 440 - &mut map, 441 - mysteryvibe::setup::MysteryVibeIdentifierFactory::default(), 442 - ); 443 - add_to_protocol_map( 444 - &mut map, 445 - mysteryvibe_v2::setup::MysteryVibeV2IdentifierFactory::default(), 446 - ); 447 - add_to_protocol_map( 448 - &mut map, 449 - nexus_revo::setup::NexusRevoIdentifierFactory::default(), 450 - ); 451 - add_to_protocol_map( 452 - &mut map, 453 - nextlevelracing::setup::NextLevelRacingIdentifierFactory::default(), 454 - ); 455 - add_to_protocol_map( 456 - &mut map, 457 - nintendo_joycon::setup::NintendoJoyconIdentifierFactory::default(), 458 - ); 459 - add_to_protocol_map(&mut map, nobra::setup::NobraIdentifierFactory::default()); 460 - add_to_protocol_map(&mut map, omobo::setup::OmoboIdentifierFactory::default()); 461 - add_to_protocol_map(&mut map, patoo::setup::PatooIdentifierFactory::default()); 462 - add_to_protocol_map( 463 - &mut map, 464 - picobong::setup::PicobongIdentifierFactory::default(), 465 - ); 466 - add_to_protocol_map( 467 - &mut map, 468 - pink_punch::setup::PinkPunchIdentifierFactory::default(), 469 - ); 470 - add_to_protocol_map( 471 - &mut map, 472 - prettylove::setup::PrettyLoveIdentifierFactory::default(), 473 - ); 474 - add_to_protocol_map( 475 - &mut map, 476 - raw_protocol::setup::RawProtocolIdentifierFactory::default(), 477 - ); 478 - add_to_protocol_map(&mut map, realov::setup::RealovIdentifierFactory::default()); 479 - add_to_protocol_map( 480 - &mut map, 481 - sakuraneko::setup::SakuranekoIdentifierFactory::default(), 482 - ); 483 - add_to_protocol_map( 484 - &mut map, 485 - satisfyer::setup::SatisfyerIdentifierFactory::default(), 486 - ); 487 - add_to_protocol_map(&mut map, sensee::setup::SenseeIdentifierFactory::default()); 488 - add_to_protocol_map( 489 - &mut map, 490 - sensee_capsule::setup::SenseeCapsuleIdentifierFactory::default(), 491 - ); 492 - add_to_protocol_map( 493 - &mut map, 494 - sensee_v2::setup::SenseeV2IdentifierFactory::default(), 495 - ); 496 - add_to_protocol_map( 497 - &mut map, 498 - sexverse_lg389::setup::SexverseLG389IdentifierFactory::default(), 499 - ); 500 - add_to_protocol_map(&mut map, serveu::setup::ServeUIdentifierFactory::default()); 501 - //add_to_protocol_map( 502 - // &mut map, 503 - // svakom::svakom_avaneo::setup::SvakomAvaNeoIdentifierFactory::default(), 504 - //); 505 - add_to_protocol_map( 506 - &mut map, 507 - svakom::svakom_alex::setup::SvakomAlexIdentifierFactory::default(), 508 - ); 509 - add_to_protocol_map( 510 - &mut map, 511 - svakom::svakom_alex_v2::setup::SvakomAlexV2IdentifierFactory::default(), 512 - ); 513 - add_to_protocol_map( 514 - &mut map, 515 - svakom::svakom_barnard::setup::SvakomBarnardIdentifierFactory::default(), 516 - ); 517 - add_to_protocol_map( 518 - &mut map, 519 - svakom::svakom_barney::setup::SvakomBarneyIdentifierFactory::default(), 520 - ); 521 - add_to_protocol_map( 522 - &mut map, 523 - svakom::svakom_dice::setup::SvakomDiceIdentifierFactory::default(), 524 - ); 525 - //add_to_protocol_map( 526 - // &mut map, 527 - // svakom::svakom_dt250a::setup::SvakomDT250AIdentifierFactory::default(), 528 - //); 529 - add_to_protocol_map( 530 - &mut map, 531 - svakom::svakom_iker::setup::SvakomIkerIdentifierFactory::default(), 532 - ); 533 - add_to_protocol_map( 534 - &mut map, 535 - svakom::svakom_jordan::setup::SvakomJordanIdentifierFactory::default(), 536 - ); 537 - add_to_protocol_map( 538 - &mut map, 539 - svakom::svakom_pulse::setup::SvakomPulseIdentifierFactory::default(), 540 - ); 541 - add_to_protocol_map( 542 - &mut map, 543 - svakom::svakom_sam::setup::SvakomSamIdentifierFactory::default(), 544 - ); 545 - add_to_protocol_map( 546 - &mut map, 547 - svakom::svakom_sam2::setup::SvakomSam2IdentifierFactory::default(), 548 - ); 549 - //add_to_protocol_map( 550 - // &mut map, 551 - // svakom::svakom_suitcase::setup::SvakomSuitcaseIdentifierFactory::default(), 552 - //); 553 - //add_to_protocol_map( 554 - // &mut map, 555 - // svakom::svakom_tarax::setup::SvakomTaraXIdentifierFactory::default(), 556 - //); 557 - add_to_protocol_map( 558 - &mut map, 559 - svakom::svakom_v1::setup::SvakomV1IdentifierFactory::default(), 560 - ); 561 - add_to_protocol_map( 562 - &mut map, 563 - svakom::svakom_v2::setup::SvakomV2IdentifierFactory::default(), 564 - ); 565 - add_to_protocol_map( 566 - &mut map, 567 - svakom::svakom_v3::setup::SvakomV3IdentifierFactory::default(), 568 - ); 569 - add_to_protocol_map( 570 - &mut map, 571 - svakom::svakom_v4::setup::SvakomV4IdentifierFactory::default(), 572 - ); 573 - add_to_protocol_map( 574 - &mut map, 575 - svakom::svakom_v5::setup::SvakomV5IdentifierFactory::default(), 576 - ); 577 - add_to_protocol_map( 578 - &mut map, 579 - svakom::svakom_v6::setup::SvakomV6IdentifierFactory::default(), 580 - ); 581 - add_to_protocol_map( 582 - &mut map, 583 - synchro::setup::SynchroIdentifierFactory::default(), 584 - ); 585 - add_to_protocol_map(&mut map, tryfun::setup::TryFunIdentifierFactory::default()); 586 - add_to_protocol_map( 587 - &mut map, 588 - tryfun_blackhole::setup::TryFunBlackHoleIdentifierFactory::default(), 589 - ); 590 - add_to_protocol_map( 591 - &mut map, 592 - tryfun_meta2::setup::TryFunMeta2IdentifierFactory::default(), 593 - ); 594 - add_to_protocol_map( 595 - &mut map, 596 - tcode_v03::setup::TCodeV03IdentifierFactory::default(), 597 - ); 598 - add_to_protocol_map( 599 - &mut map, 600 - vibcrafter::setup::VibCrafterIdentifierFactory::default(), 601 - ); 602 - add_to_protocol_map( 603 - &mut map, 604 - vibratissimo::setup::VibratissimoIdentifierFactory::default(), 605 - ); 606 - add_to_protocol_map( 607 - &mut map, 608 - vorze_sa::setup::VorzeSAIdentifierFactory::default(), 609 - ); 610 - add_to_protocol_map(&mut map, wetoy::setup::WeToyIdentifierFactory::default()); 611 - add_to_protocol_map(&mut map, wevibe::setup::WeVibeIdentifierFactory::default()); 612 - add_to_protocol_map( 613 - &mut map, 614 - wevibe8bit::setup::WeVibe8BitIdentifierFactory::default(), 615 - ); 616 - add_to_protocol_map( 617 - &mut map, 618 - wevibe_chorus::setup::WeVibeChorusIdentifierFactory::default(), 619 - ); 620 - add_to_protocol_map(&mut map, xibao::setup::XibaoIdentifierFactory::default()); 621 - add_to_protocol_map(&mut map, xinput::setup::XInputIdentifierFactory::default()); 622 - add_to_protocol_map( 623 - &mut map, 624 - xiuxiuda::setup::XiuxiudaIdentifierFactory::default(), 625 - ); 626 - add_to_protocol_map( 627 - &mut map, 628 - xuanhuan::setup::XuanhuanIdentifierFactory::default(), 629 - ); 630 - add_to_protocol_map( 631 - &mut map, 632 - youcups::setup::YoucupsIdentifierFactory::default(), 633 - ); 634 - add_to_protocol_map(&mut map, youou::setup::YououIdentifierFactory::default()); 635 - add_to_protocol_map(&mut map, zalo::setup::ZaloIdentifierFactory::default()); 636 - add_to_protocol_map( 637 - &mut map, 638 - kgoal_boost::setup::KGoalBoostIdentifierFactory::default(), 639 - ); 640 - map 641 - } 642 - 643 - pub enum ProtocolValueCommandPrefilterStrategy { 644 - /// Drop repeated ValueCmd/ValueWithParameterCmd messages 645 - DropRepeats, 646 - /// No filter, send all value messages for processing 647 - None, 648 - } 649 - 650 - fn print_type_of<T>(_: &T) -> &'static str { 651 - std::any::type_name::<T>() 652 - } 653 - 654 - pub struct ProtocolSpecializer { 655 - specifiers: Vec<ProtocolCommunicationSpecifier>, 656 - identifier: Box<dyn ProtocolIdentifier>, 657 - } 658 - 659 - impl ProtocolSpecializer { 660 - pub fn new( 661 - specifiers: Vec<ProtocolCommunicationSpecifier>, 662 - identifier: Box<dyn ProtocolIdentifier>, 663 - ) -> Self { 664 - Self { 665 - specifiers, 666 - identifier, 667 - } 668 - } 669 - 670 - pub fn specifiers(&self) -> &Vec<ProtocolCommunicationSpecifier> { 671 - &self.specifiers 672 - } 673 - 674 - pub fn identify(self) -> Box<dyn ProtocolIdentifier> { 675 - self.identifier 676 - } 677 - } 678 - 679 - #[async_trait] 680 - pub trait ProtocolIdentifier: Sync + Send { 681 - async fn identify( 682 - &mut self, 683 - hardware: Arc<Hardware>, 684 - specifier: ProtocolCommunicationSpecifier, 685 - ) -> Result<(UserDeviceIdentifier, Box<dyn ProtocolInitializer>), ButtplugDeviceError>; 686 - } 687 - 688 - #[async_trait] 689 - pub trait ProtocolInitializer: Sync + Send { 690 - async fn initialize( 691 - &mut self, 692 - hardware: Arc<Hardware>, 693 - device_definition: &DeviceDefinition, 694 - ) -> Result<Arc<dyn ProtocolHandler>, ButtplugDeviceError>; 695 - } 696 - 697 - pub struct GenericProtocolIdentifier { 698 - handler: Option<Arc<dyn ProtocolHandler>>, 699 - protocol_identifier: String, 700 - } 701 - 702 - impl GenericProtocolIdentifier { 703 - pub fn new(handler: Arc<dyn ProtocolHandler>, protocol_identifier: &str) -> Self { 704 - Self { 705 - handler: Some(handler), 706 - protocol_identifier: protocol_identifier.to_owned(), 707 - } 708 - } 709 - } 710 - 711 - #[async_trait] 712 - impl ProtocolIdentifier for GenericProtocolIdentifier { 713 - async fn identify( 714 - &mut self, 715 - hardware: Arc<Hardware>, 716 - _: ProtocolCommunicationSpecifier, 717 - ) -> Result<(UserDeviceIdentifier, Box<dyn ProtocolInitializer>), ButtplugDeviceError> { 718 - let device_identifier = UserDeviceIdentifier::new( 719 - hardware.address(), 720 - &self.protocol_identifier, 721 - &Some(hardware.name().to_owned()), 722 - ); 723 - Ok(( 724 - device_identifier, 725 - Box::new(GenericProtocolInitializer::new( 726 - self.handler.take().unwrap(), 727 - )), 728 - )) 729 - } 730 - } 731 - 732 - pub struct GenericProtocolInitializer { 733 - handler: Option<Arc<dyn ProtocolHandler>>, 734 - } 735 - 736 - impl GenericProtocolInitializer { 737 - pub fn new(handler: Arc<dyn ProtocolHandler>) -> Self { 738 - Self { 739 - handler: Some(handler), 740 - } 741 - } 742 - } 743 - 744 - #[async_trait] 745 - impl ProtocolInitializer for GenericProtocolInitializer { 746 - async fn initialize( 747 - &mut self, 748 - _: Arc<Hardware>, 749 - _: &DeviceDefinition, 750 - ) -> Result<Arc<dyn ProtocolHandler>, ButtplugDeviceError> { 751 - Ok(self.handler.take().unwrap()) 752 - } 753 - } 754 - 755 - pub trait ProtocolHandler: Sync + Send { 756 - fn keepalive_strategy(&self) -> ProtocolKeepaliveStrategy { 757 - ProtocolKeepaliveStrategy::HardwareRequiredRepeatLastPacketStrategy 758 - } 759 - 760 - fn handle_message( 761 - &self, 762 - message: &ButtplugDeviceCommandMessageUnionV4, 763 - ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 764 - self.command_unimplemented(print_type_of(&message)) 765 - } 766 - 767 - // Allow here since this changes between debug/release 768 - #[allow(unused_variables)] 769 - fn command_unimplemented( 770 - &self, 771 - command: &str, 772 - ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 773 - #[cfg(debug_assertions)] 774 - unimplemented!("Command not implemented for this protocol"); 775 - #[cfg(not(debug_assertions))] 776 - Err(ButtplugDeviceError::UnhandledCommand(format!( 777 - "Command not implemented for this protocol: {}", 778 - command 779 - ))) 780 - } 781 - 782 - // The default scalar handler assumes that most devices require discrete commands per feature. If 783 - // a protocol has commands that combine multiple features, either with matched or unmatched 784 - // actuators, they should just implement their own version of this method. 785 - fn handle_output_cmd( 786 - &self, 787 - cmd: &CheckedOutputCmdV4, 788 - ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 789 - let output_command = cmd.output_command(); 790 - match output_command { 791 - OutputCommand::Constrict(x) => { 792 - self.handle_output_constrict_cmd(cmd.feature_index(), cmd.feature_id(), x.value()) 793 - } 794 - OutputCommand::Inflate(x) => { 795 - self.handle_output_inflate_cmd(cmd.feature_index(), cmd.feature_id(), x.value()) 796 - } 797 - OutputCommand::Oscillate(x) => { 798 - self.handle_output_oscillate_cmd(cmd.feature_index(), cmd.feature_id(), x.value()) 799 - } 800 - OutputCommand::Rotate(x) => { 801 - self.handle_output_rotate_cmd(cmd.feature_index(), cmd.feature_id(), x.value()) 802 - } 803 - OutputCommand::Vibrate(x) => { 804 - self.handle_output_vibrate_cmd(cmd.feature_index(), cmd.feature_id(), x.value()) 805 - } 806 - OutputCommand::Position(x) => { 807 - self.handle_output_position_cmd(cmd.feature_index(), cmd.feature_id(), x.value()) 808 - } 809 - OutputCommand::Heater(x) => { 810 - self.handle_output_heater_cmd(cmd.feature_index(), cmd.feature_id(), x.value()) 811 - } 812 - OutputCommand::Led(x) => { 813 - self.handle_output_led_cmd(cmd.feature_index(), cmd.feature_id(), x.value()) 814 - } 815 - OutputCommand::PositionWithDuration(x) => self.handle_position_with_duration_cmd( 816 - cmd.feature_index(), 817 - cmd.feature_id(), 818 - x.position(), 819 - x.duration(), 820 - ), 821 - OutputCommand::RotateWithDirection(x) => self.handle_rotation_with_direction_cmd( 822 - cmd.feature_index(), 823 - cmd.feature_id(), 824 - x.speed(), 825 - x.clockwise(), 826 - ), 827 - } 828 - } 829 - 830 - fn handle_output_vibrate_cmd( 831 - &self, 832 - _feature_index: u32, 833 - _feature_id: Uuid, 834 - _speed: u32, 835 - ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 836 - self.command_unimplemented("OutputCmd (Vibrate Actuator)") 837 - } 838 - 839 - fn handle_output_rotate_cmd( 840 - &self, 841 - _feature_index: u32, 842 - _feature_id: Uuid, 843 - _speed: u32, 844 - ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 845 - self.command_unimplemented("OutputCmd (Rotate Actuator)") 846 - } 847 - 848 - fn handle_output_oscillate_cmd( 849 - &self, 850 - _feature_index: u32, 851 - _feature_id: Uuid, 852 - _speed: u32, 853 - ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 854 - self.command_unimplemented("OutputCmd (Oscillate Actuator)") 855 - } 856 - 857 - fn handle_output_inflate_cmd( 858 - &self, 859 - _feature_index: u32, 860 - _feature_id: Uuid, 861 - _level: u32, 862 - ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 863 - self.command_unimplemented("OutputCmd (Inflate Actuator)") 864 - } 865 - 866 - fn handle_output_constrict_cmd( 867 - &self, 868 - _feature_index: u32, 869 - _feature_id: Uuid, 870 - _level: u32, 871 - ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 872 - self.command_unimplemented("OutputCmd (Constrict Actuator)") 873 - } 874 - 875 - fn handle_output_heater_cmd( 876 - &self, 877 - _feature_index: u32, 878 - _feature_id: Uuid, 879 - _level: u32, 880 - ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 881 - self.command_unimplemented("OutputCmd (Heater Actuator)") 882 - } 883 - 884 - fn handle_output_led_cmd( 885 - &self, 886 - _feature_index: u32, 887 - _feature_id: Uuid, 888 - _level: u32, 889 - ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 890 - self.command_unimplemented("OutputCmd (Led Actuator)") 891 - } 892 - 893 - fn handle_output_position_cmd( 894 - &self, 895 - _feature_index: u32, 896 - _feature_id: Uuid, 897 - _position: u32, 898 - ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 899 - self.command_unimplemented("OutputCmd (Position Actuator)") 900 - } 901 - 902 - fn handle_position_with_duration_cmd( 903 - &self, 904 - _feature_index: u32, 905 - _feature_id: Uuid, 906 - _position: u32, 907 - _duration: u32, 908 - ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 909 - self.command_unimplemented("OutputCmd (Position w/ Duration Actuator)") 910 - } 911 - 912 - fn handle_rotation_with_direction_cmd( 913 - &self, 914 - _feature_index: u32, 915 - _feature_id: Uuid, 916 - _speed: u32, 917 - _clockwise: bool, 918 - ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 919 - self.command_unimplemented("OutputCmd (Rotation w/ Direction Actuator)") 920 - } 921 - 922 - fn handle_input_subscribe_cmd( 923 - &self, 924 - _device_index: u32, 925 - _device: Arc<Hardware>, 926 - _feature_index: u32, 927 - _feature_id: Uuid, 928 - _sensor_type: InputType, 929 - ) -> BoxFuture<Result<(), ButtplugDeviceError>> { 930 - future::ready(Err(ButtplugDeviceError::UnhandledCommand( 931 - "Command not implemented for this protocol: InputCmd (Subscribe)".to_string(), 932 - ))) 933 - .boxed() 934 - } 935 - 936 - fn handle_input_unsubscribe_cmd( 937 - &self, 938 - _device: Arc<Hardware>, 939 - _feature_index: u32, 940 - _feature_id: Uuid, 941 - _sensor_type: InputType, 942 - ) -> BoxFuture<Result<(), ButtplugDeviceError>> { 943 - future::ready(Err(ButtplugDeviceError::UnhandledCommand( 944 - "Command not implemented for this protocol: InputCmd (Unsubscribe)".to_string(), 945 - ))) 946 - .boxed() 947 - } 948 - 949 - fn handle_input_read_cmd( 950 - &self, 951 - device_index: u32, 952 - device: Arc<Hardware>, 953 - feature_index: u32, 954 - feature_id: Uuid, 955 - sensor_type: InputType, 956 - ) -> BoxFuture<Result<InputReadingV4, ButtplugDeviceError>> { 957 - match sensor_type { 958 - InputType::Battery => { 959 - self.handle_battery_level_cmd(device_index, device, feature_index, feature_id) 960 - } 961 - _ => future::ready(Err(ButtplugDeviceError::UnhandledCommand( 962 - "Command not implemented for this protocol: InputCmd (Read)".to_string(), 963 - ))) 964 - .boxed(), 965 - } 966 - } 967 - 968 - // Handle Battery Level returns a SensorReading, as we'll always need to do a sensor index 969 - // conversion on it. 970 - fn handle_battery_level_cmd( 971 - &self, 972 - device_index: u32, 973 - device: Arc<Hardware>, 974 - feature_index: u32, 975 - feature_id: Uuid, 976 - ) -> BoxFuture<Result<InputReadingV4, ButtplugDeviceError>> { 977 - // If we have a standardized BLE Battery endpoint, handle that above the 978 - // protocol, as it'll always be the same. 979 - if device.endpoints().contains(&Endpoint::RxBLEBattery) { 980 - debug!("Trying to get battery reading."); 981 - let msg = HardwareReadCmd::new(feature_id, Endpoint::RxBLEBattery, 1, 0); 982 - let fut = device.read_value(&msg); 983 - async move { 984 - let hw_msg = fut.await?; 985 - let battery_level = hw_msg.data()[0] as i32; 986 - let battery_reading = InputReadingV4::new( 987 - device_index, 988 - feature_index, 989 - InputType::Battery, 990 - vec![battery_level], 991 - ); 992 - debug!("Got battery reading: {}", battery_level); 993 - Ok(battery_reading) 994 - } 995 - .boxed() 996 - } else { 997 - future::ready(Err(ButtplugDeviceError::UnhandledCommand( 998 - "Command not implemented for this protocol: SensorReadCmd".to_string(), 999 - ))) 1000 - .boxed() 1001 - } 1002 - } 1003 - 1004 - fn handle_rssi_level_cmd( 1005 - &self, 1006 - _device: Arc<Hardware>, 1007 - _feature_index: u32, 1008 - _feature_id: Uuid, 1009 - ) -> BoxFuture<Result<(), ButtplugDeviceError>> { 1010 - future::ready(Err(ButtplugDeviceError::UnhandledCommand( 1011 - "Command not implemented for this protocol: SensorReadCmd".to_string(), 1012 - ))) 1013 - .boxed() 1014 - } 1015 - 1016 - fn event_stream( 1017 - &self, 1018 - ) -> Pin<Box<dyn tokio_stream::Stream<Item = ButtplugServerDeviceMessage> + Send>> { 1019 - tokio_stream::empty().boxed() 1020 - } 1021 - } 1022 - 1023 - #[macro_export] 1024 - macro_rules! generic_protocol_setup { 1025 - ( $protocol_name:ident, $protocol_identifier:tt) => { 1026 - paste::paste! { 1027 - pub mod setup { 1028 - use std::sync::Arc; 1029 - use $crate::device::protocol::{ 1030 - GenericProtocolIdentifier, ProtocolIdentifier, ProtocolIdentifierFactory, 1031 - }; 1032 - #[derive(Default)] 1033 - pub struct [< $protocol_name IdentifierFactory >] {} 1034 - 1035 - impl ProtocolIdentifierFactory for [< $protocol_name IdentifierFactory >] { 1036 - fn identifier(&self) -> &str { 1037 - $protocol_identifier 1038 - } 1039 - 1040 - fn create(&self) -> Box<dyn ProtocolIdentifier> { 1041 - Box::new(GenericProtocolIdentifier::new( 1042 - Arc::new(super::$protocol_name::default()), 1043 - self.identifier(), 1044 - )) 1045 - } 1046 - } 1047 - } 1048 - } 1049 - }; 1050 - } 1051 - 1052 - #[macro_export] 1053 - macro_rules! generic_protocol_initializer_setup { 1054 - ( $protocol_name:ident, $protocol_identifier:tt) => { 1055 - paste::paste! { 1056 - pub mod setup { 1057 - use $crate::device::protocol::{ProtocolIdentifier, ProtocolIdentifierFactory}; 1058 - #[derive(Default)] 1059 - pub struct [< $protocol_name IdentifierFactory >] {} 1060 - 1061 - impl ProtocolIdentifierFactory for [< $protocol_name IdentifierFactory >] { 1062 - fn identifier(&self) -> &str { 1063 - $protocol_identifier 1064 - } 1065 - 1066 - fn create(&self) -> Box<dyn ProtocolIdentifier> { 1067 - Box::new(super::[< $protocol_name Identifier >]::default()) 1068 - } 1069 - } 1070 - } 1071 - 1072 - #[derive(Default)] 1073 - pub struct [< $protocol_name Identifier >] {} 1074 - 1075 - #[async_trait] 1076 - impl ProtocolIdentifier for [< $protocol_name Identifier >] { 1077 - async fn identify( 1078 - &mut self, 1079 - hardware: Arc<Hardware>, 1080 - _: ProtocolCommunicationSpecifier, 1081 - ) -> Result<(UserDeviceIdentifier, Box<dyn ProtocolInitializer>), ButtplugDeviceError> { 1082 - Ok((UserDeviceIdentifier::new(hardware.address(), $protocol_identifier, &Some(hardware.name().to_owned())), Box::new([< $protocol_name Initializer >]::default()))) 1083 - } 1084 - } 1085 - } 1086 - }; 1087 - } 1088 - 1089 - pub use generic_protocol_initializer_setup; 1090 - pub use generic_protocol_setup; 1091 - 1092 - use super::hardware::HardwareWriteCmd;
crates/buttplug_server/src/device/protocol/monsterpub.rs crates/buttplug_server/src/device/protocol_impl/monsterpub.rs
crates/buttplug_server/src/device/protocol/motorbunny.rs crates/buttplug_server/src/device/protocol_impl/motorbunny.rs
crates/buttplug_server/src/device/protocol/mysteryvibe.rs crates/buttplug_server/src/device/protocol_impl/mysteryvibe.rs
crates/buttplug_server/src/device/protocol/mysteryvibe_v2.rs crates/buttplug_server/src/device/protocol_impl/mysteryvibe_v2.rs
crates/buttplug_server/src/device/protocol/nextlevelracing.rs crates/buttplug_server/src/device/protocol_impl/nextlevelracing.rs
crates/buttplug_server/src/device/protocol/nexus_revo.rs crates/buttplug_server/src/device/protocol_impl/nexus_revo.rs
crates/buttplug_server/src/device/protocol/nintendo_joycon.rs crates/buttplug_server/src/device/protocol_impl/nintendo_joycon.rs
crates/buttplug_server/src/device/protocol/nobra.rs crates/buttplug_server/src/device/protocol_impl/nobra.rs
crates/buttplug_server/src/device/protocol/omobo.rs crates/buttplug_server/src/device/protocol_impl/omobo.rs
crates/buttplug_server/src/device/protocol/patoo.rs crates/buttplug_server/src/device/protocol_impl/patoo.rs
crates/buttplug_server/src/device/protocol/picobong.rs crates/buttplug_server/src/device/protocol_impl/picobong.rs
crates/buttplug_server/src/device/protocol/pink_punch.rs crates/buttplug_server/src/device/protocol_impl/pink_punch.rs
crates/buttplug_server/src/device/protocol/prettylove.rs crates/buttplug_server/src/device/protocol_impl/prettylove.rs
crates/buttplug_server/src/device/protocol/raw_protocol.rs crates/buttplug_server/src/device/protocol_impl/raw_protocol.rs
crates/buttplug_server/src/device/protocol/realov.rs crates/buttplug_server/src/device/protocol_impl/realov.rs
crates/buttplug_server/src/device/protocol/sakuraneko.rs crates/buttplug_server/src/device/protocol_impl/sakuraneko.rs
crates/buttplug_server/src/device/protocol/satisfyer.rs crates/buttplug_server/src/device/protocol_impl/satisfyer.rs
crates/buttplug_server/src/device/protocol/sensee.rs crates/buttplug_server/src/device/protocol_impl/sensee.rs
crates/buttplug_server/src/device/protocol/sensee_capsule.rs crates/buttplug_server/src/device/protocol_impl/sensee_capsule.rs
crates/buttplug_server/src/device/protocol/sensee_v2.rs crates/buttplug_server/src/device/protocol_impl/sensee_v2.rs
crates/buttplug_server/src/device/protocol/serveu.rs crates/buttplug_server/src/device/protocol_impl/serveu.rs
crates/buttplug_server/src/device/protocol/sexverse_lg389.rs crates/buttplug_server/src/device/protocol_impl/sexverse_lg389.rs
crates/buttplug_server/src/device/protocol/svakom/mod.rs crates/buttplug_server/src/device/protocol_impl/svakom/mod.rs
crates/buttplug_server/src/device/protocol/svakom/svakom_alex.rs crates/buttplug_server/src/device/protocol_impl/svakom/svakom_alex.rs
crates/buttplug_server/src/device/protocol/svakom/svakom_alex_v2.rs crates/buttplug_server/src/device/protocol_impl/svakom/svakom_alex_v2.rs
crates/buttplug_server/src/device/protocol/svakom/svakom_avaneo.rs crates/buttplug_server/src/device/protocol_impl/svakom/svakom_avaneo.rs
crates/buttplug_server/src/device/protocol/svakom/svakom_barnard.rs crates/buttplug_server/src/device/protocol_impl/svakom/svakom_barnard.rs
crates/buttplug_server/src/device/protocol/svakom/svakom_barney.rs crates/buttplug_server/src/device/protocol_impl/svakom/svakom_barney.rs
crates/buttplug_server/src/device/protocol/svakom/svakom_dice.rs crates/buttplug_server/src/device/protocol_impl/svakom/svakom_dice.rs
crates/buttplug_server/src/device/protocol/svakom/svakom_dt250a.rs crates/buttplug_server/src/device/protocol_impl/svakom/svakom_dt250a.rs
crates/buttplug_server/src/device/protocol/svakom/svakom_iker.rs crates/buttplug_server/src/device/protocol_impl/svakom/svakom_iker.rs
crates/buttplug_server/src/device/protocol/svakom/svakom_jordan.rs crates/buttplug_server/src/device/protocol_impl/svakom/svakom_jordan.rs
crates/buttplug_server/src/device/protocol/svakom/svakom_pulse.rs crates/buttplug_server/src/device/protocol_impl/svakom/svakom_pulse.rs
crates/buttplug_server/src/device/protocol/svakom/svakom_sam.rs crates/buttplug_server/src/device/protocol_impl/svakom/svakom_sam.rs
crates/buttplug_server/src/device/protocol/svakom/svakom_sam2.rs crates/buttplug_server/src/device/protocol_impl/svakom/svakom_sam2.rs
crates/buttplug_server/src/device/protocol/svakom/svakom_suitcase.rs crates/buttplug_server/src/device/protocol_impl/svakom/svakom_suitcase.rs
crates/buttplug_server/src/device/protocol/svakom/svakom_tarax.rs crates/buttplug_server/src/device/protocol_impl/svakom/svakom_tarax.rs
crates/buttplug_server/src/device/protocol/svakom/svakom_v1.rs crates/buttplug_server/src/device/protocol_impl/svakom/svakom_v1.rs
crates/buttplug_server/src/device/protocol/svakom/svakom_v2.rs crates/buttplug_server/src/device/protocol_impl/svakom/svakom_v2.rs
crates/buttplug_server/src/device/protocol/svakom/svakom_v3.rs crates/buttplug_server/src/device/protocol_impl/svakom/svakom_v3.rs
crates/buttplug_server/src/device/protocol/svakom/svakom_v4.rs crates/buttplug_server/src/device/protocol_impl/svakom/svakom_v4.rs
crates/buttplug_server/src/device/protocol/svakom/svakom_v5.rs crates/buttplug_server/src/device/protocol_impl/svakom/svakom_v5.rs
crates/buttplug_server/src/device/protocol/svakom/svakom_v6.rs crates/buttplug_server/src/device/protocol_impl/svakom/svakom_v6.rs
crates/buttplug_server/src/device/protocol/synchro.rs crates/buttplug_server/src/device/protocol_impl/synchro.rs
crates/buttplug_server/src/device/protocol/tcode_v03.rs crates/buttplug_server/src/device/protocol_impl/tcode_v03.rs
crates/buttplug_server/src/device/protocol/thehandy/handyplug.proto crates/buttplug_server/src/device/protocol_impl/thehandy/handyplug.proto
crates/buttplug_server/src/device/protocol/thehandy/handyplug.rs crates/buttplug_server/src/device/protocol_impl/thehandy/handyplug.rs
crates/buttplug_server/src/device/protocol/thehandy/mod.rs crates/buttplug_server/src/device/protocol_impl/thehandy/mod.rs
crates/buttplug_server/src/device/protocol/thehandy/protocomm.proto crates/buttplug_server/src/device/protocol_impl/thehandy/protocomm.proto
crates/buttplug_server/src/device/protocol/thehandy/protocomm.rs crates/buttplug_server/src/device/protocol_impl/thehandy/protocomm.rs
crates/buttplug_server/src/device/protocol/tryfun.rs crates/buttplug_server/src/device/protocol_impl/tryfun.rs
crates/buttplug_server/src/device/protocol/tryfun_blackhole.rs crates/buttplug_server/src/device/protocol_impl/tryfun_blackhole.rs
crates/buttplug_server/src/device/protocol/tryfun_meta2.rs crates/buttplug_server/src/device/protocol_impl/tryfun_meta2.rs
crates/buttplug_server/src/device/protocol/vibcrafter.rs crates/buttplug_server/src/device/protocol_impl/vibcrafter.rs
crates/buttplug_server/src/device/protocol/vibratissimo.rs crates/buttplug_server/src/device/protocol_impl/vibratissimo.rs
crates/buttplug_server/src/device/protocol/vorze_sa/dual_rotator.rs crates/buttplug_server/src/device/protocol_impl/vorze_sa/dual_rotator.rs
crates/buttplug_server/src/device/protocol/vorze_sa/mod.rs crates/buttplug_server/src/device/protocol_impl/vorze_sa/mod.rs
crates/buttplug_server/src/device/protocol/vorze_sa/piston.rs crates/buttplug_server/src/device/protocol_impl/vorze_sa/piston.rs
crates/buttplug_server/src/device/protocol/vorze_sa/single_rotator.rs crates/buttplug_server/src/device/protocol_impl/vorze_sa/single_rotator.rs
crates/buttplug_server/src/device/protocol/vorze_sa/vibrator.rs crates/buttplug_server/src/device/protocol_impl/vorze_sa/vibrator.rs
crates/buttplug_server/src/device/protocol/wetoy.rs crates/buttplug_server/src/device/protocol_impl/wetoy.rs
crates/buttplug_server/src/device/protocol/wevibe.rs crates/buttplug_server/src/device/protocol_impl/wevibe.rs
crates/buttplug_server/src/device/protocol/wevibe8bit.rs crates/buttplug_server/src/device/protocol_impl/wevibe8bit.rs
crates/buttplug_server/src/device/protocol/wevibe_chorus.rs crates/buttplug_server/src/device/protocol_impl/wevibe_chorus.rs
crates/buttplug_server/src/device/protocol/xibao.rs crates/buttplug_server/src/device/protocol_impl/xibao.rs
crates/buttplug_server/src/device/protocol/xinput.rs crates/buttplug_server/src/device/protocol_impl/xinput.rs
crates/buttplug_server/src/device/protocol/xiuxiuda.rs crates/buttplug_server/src/device/protocol_impl/xiuxiuda.rs
crates/buttplug_server/src/device/protocol/xuanhuan.rs crates/buttplug_server/src/device/protocol_impl/xuanhuan.rs
crates/buttplug_server/src/device/protocol/youcups.rs crates/buttplug_server/src/device/protocol_impl/youcups.rs
crates/buttplug_server/src/device/protocol/youou.rs crates/buttplug_server/src/device/protocol_impl/youou.rs
crates/buttplug_server/src/device/protocol/zalo.rs crates/buttplug_server/src/device/protocol_impl/zalo.rs
+572
crates/buttplug_server/src/device/protocol_impl/mod.rs
··· 1 + use std::{collections::HashMap, sync::Arc}; 2 + 3 + use crate::device::protocol::ProtocolIdentifierFactory; 4 + 5 + 6 + // Utility mods 7 + pub mod fleshlight_launch_helper; 8 + 9 + // Since users can pick and choose protocols, we need all of these to be public. 10 + pub mod activejoy; 11 + pub mod adrienlastic; 12 + pub mod amorelie_joy; 13 + pub mod aneros; 14 + pub mod ankni; 15 + pub mod bananasome; 16 + pub mod cachito; 17 + pub mod cowgirl; 18 + pub mod cowgirl_cone; 19 + pub mod cupido; 20 + pub mod deepsire; 21 + pub mod feelingso; 22 + pub mod fleshy_thrust; 23 + pub mod foreo; 24 + pub mod fox; 25 + pub mod fredorch; 26 + pub mod fredorch_rotary; 27 + pub mod galaku; 28 + pub mod galaku_pump; 29 + pub mod hgod; 30 + pub mod hismith; 31 + pub mod hismith_mini; 32 + pub mod htk_bm; 33 + pub mod itoys; 34 + pub mod jejoue; 35 + // pub mod joyhub; 36 + // pub mod joyhub_v2; 37 + pub mod joyhub_v3; 38 + // pub mod joyhub_v4; 39 + // pub mod joyhub_v5; 40 + // pub mod joyhub_v6; 41 + pub mod kgoal_boost; 42 + pub mod kiiroo_prowand; 43 + pub mod kiiroo_spot; 44 + pub mod kiiroo_v2; 45 + pub mod kiiroo_v21; 46 + pub mod kiiroo_v21_initialized; 47 + pub mod kiiroo_v2_vibrator; 48 + pub mod kizuna; 49 + pub mod lelo_harmony; 50 + pub mod lelof1s; 51 + pub mod lelof1sv2; 52 + pub mod leten; 53 + pub mod libo_elle; 54 + pub mod libo_shark; 55 + pub mod libo_vibes; 56 + pub mod lioness; 57 + pub mod loob; 58 + pub mod lovedistance; 59 + pub mod lovehoney_desire; 60 + pub mod lovense; 61 + // pub mod lovense_connect_service; 62 + pub mod lovenuts; 63 + pub mod luvmazer; 64 + pub mod magic_motion_v1; 65 + pub mod magic_motion_v2; 66 + pub mod magic_motion_v3; 67 + pub mod magic_motion_v4; 68 + pub mod mannuo; 69 + pub mod maxpro; 70 + pub mod meese; 71 + pub mod metaxsire; 72 + pub mod metaxsire_v2; 73 + pub mod metaxsire_v3; 74 + mod metaxsire_v4; 75 + pub mod mizzzee; 76 + pub mod mizzzee_v2; 77 + pub mod mizzzee_v3; 78 + pub mod monsterpub; 79 + pub mod motorbunny; 80 + pub mod mysteryvibe; 81 + pub mod mysteryvibe_v2; 82 + pub mod nextlevelracing; 83 + pub mod nexus_revo; 84 + pub mod nintendo_joycon; 85 + pub mod nobra; 86 + pub mod omobo; 87 + pub mod patoo; 88 + pub mod picobong; 89 + pub mod pink_punch; 90 + pub mod prettylove; 91 + pub mod raw_protocol; 92 + pub mod realov; 93 + pub mod sakuraneko; 94 + pub mod satisfyer; 95 + pub mod sensee; 96 + pub mod sensee_capsule; 97 + pub mod sensee_v2; 98 + pub mod serveu; 99 + pub mod sexverse_lg389; 100 + pub mod svakom; 101 + pub mod synchro; 102 + pub mod tcode_v03; 103 + pub mod thehandy; 104 + pub mod tryfun; 105 + pub mod tryfun_blackhole; 106 + pub mod tryfun_meta2; 107 + pub mod vibcrafter; 108 + pub mod vibratissimo; 109 + pub mod vorze_sa; 110 + pub mod wetoy; 111 + pub mod wevibe; 112 + pub mod wevibe8bit; 113 + pub mod wevibe_chorus; 114 + pub mod xibao; 115 + pub mod xinput; 116 + pub mod xiuxiuda; 117 + pub mod xuanhuan; 118 + pub mod youcups; 119 + pub mod youou; 120 + pub mod zalo; 121 + 122 + pub fn get_default_protocol_map() -> HashMap<String, Arc<dyn ProtocolIdentifierFactory>> { 123 + let mut map = HashMap::new(); 124 + fn add_to_protocol_map<T>( 125 + map: &mut HashMap<String, Arc<dyn ProtocolIdentifierFactory>>, 126 + factory: T, 127 + ) where 128 + T: ProtocolIdentifierFactory + 'static, 129 + { 130 + let factory = Arc::new(factory); 131 + map.insert(factory.identifier().to_owned(), factory); 132 + } 133 + 134 + add_to_protocol_map( 135 + &mut map, 136 + activejoy::setup::ActiveJoyIdentifierFactory::default(), 137 + ); 138 + add_to_protocol_map( 139 + &mut map, 140 + adrienlastic::setup::AdrienLasticIdentifierFactory::default(), 141 + ); 142 + add_to_protocol_map( 143 + &mut map, 144 + amorelie_joy::setup::AmorelieJoyIdentifierFactory::default(), 145 + ); 146 + add_to_protocol_map(&mut map, aneros::setup::AnerosIdentifierFactory::default()); 147 + add_to_protocol_map(&mut map, ankni::setup::AnkniIdentifierFactory::default()); 148 + add_to_protocol_map( 149 + &mut map, 150 + bananasome::setup::BananasomeIdentifierFactory::default(), 151 + ); 152 + add_to_protocol_map( 153 + &mut map, 154 + cachito::setup::CachitoIdentifierFactory::default(), 155 + ); 156 + add_to_protocol_map( 157 + &mut map, 158 + cowgirl::setup::CowgirlIdentifierFactory::default(), 159 + ); 160 + add_to_protocol_map( 161 + &mut map, 162 + cowgirl_cone::setup::CowgirlConeIdentifierFactory::default(), 163 + ); 164 + add_to_protocol_map(&mut map, cupido::setup::CupidoIdentifierFactory::default()); 165 + add_to_protocol_map( 166 + &mut map, 167 + deepsire::setup::DeepSireIdentifierFactory::default(), 168 + ); 169 + add_to_protocol_map( 170 + &mut map, 171 + lovense::setup::LovenseIdentifierFactory::default(), 172 + ); 173 + add_to_protocol_map( 174 + &mut map, 175 + hismith::setup::HismithIdentifierFactory::default(), 176 + ); 177 + add_to_protocol_map( 178 + &mut map, 179 + hismith_mini::setup::HismithMiniIdentifierFactory::default(), 180 + ); 181 + add_to_protocol_map(&mut map, htk_bm::setup::HtkBmIdentifierFactory::default()); 182 + add_to_protocol_map( 183 + &mut map, 184 + thehandy::setup::TheHandyIdentifierFactory::default(), 185 + ); 186 + 187 + add_to_protocol_map( 188 + &mut map, 189 + feelingso::setup::FeelingSoIdentifierFactory::default(), 190 + ); 191 + add_to_protocol_map( 192 + &mut map, 193 + fleshy_thrust::setup::FleshyThrustIdentifierFactory::default(), 194 + ); 195 + add_to_protocol_map(&mut map, foreo::setup::ForeoIdentifierFactory::default()); 196 + add_to_protocol_map(&mut map, fox::setup::FoxIdentifierFactory::default()); 197 + add_to_protocol_map( 198 + &mut map, 199 + fredorch::setup::FredorchIdentifierFactory::default(), 200 + ); 201 + add_to_protocol_map( 202 + &mut map, 203 + fredorch_rotary::setup::FredorchRotaryIdentifierFactory::default(), 204 + ); 205 + 206 + add_to_protocol_map(&mut map, hgod::setup::HgodIdentifierFactory::default()); 207 + 208 + add_to_protocol_map( 209 + &mut map, 210 + galaku_pump::setup::GalakuPumpIdentifierFactory::default(), 211 + ); 212 + 213 + add_to_protocol_map(&mut map, galaku::setup::GalakuIdentifierFactory::default()); 214 + 215 + add_to_protocol_map(&mut map, itoys::setup::IToysIdentifierFactory::default()); 216 + add_to_protocol_map(&mut map, jejoue::setup::JeJoueIdentifierFactory::default()); 217 + // add_to_protocol_map(&mut map, joyhub::setup::JoyHubIdentifierFactory::default()); 218 + // add_to_protocol_map( 219 + // &mut map, 220 + // joyhub_v2::setup::JoyHubV2IdentifierFactory::default(), 221 + // ); 222 + 223 + add_to_protocol_map( 224 + &mut map, 225 + joyhub_v3::setup::JoyHubV3IdentifierFactory::default(), 226 + ); 227 + 228 + // add_to_protocol_map( 229 + // &mut map, 230 + // joyhub_v4::setup::JoyHubV4IdentifierFactory::default(), 231 + // ); 232 + // add_to_protocol_map( 233 + // &mut map, 234 + // joyhub_v5::setup::JoyHubV5IdentifierFactory::default(), 235 + // ); 236 + // add_to_protocol_map( 237 + // &mut map, 238 + // joyhub_v6::setup::JoyHubV6IdentifierFactory::default(), 239 + // ); 240 + add_to_protocol_map( 241 + &mut map, 242 + kiiroo_prowand::setup::KiirooProWandIdentifierFactory::default(), 243 + ); 244 + add_to_protocol_map( 245 + &mut map, 246 + kiiroo_spot::setup::KiirooSpotIdentifierFactory::default(), 247 + ); 248 + add_to_protocol_map( 249 + &mut map, 250 + kiiroo_v2::setup::KiirooV2IdentifierFactory::default(), 251 + ); 252 + add_to_protocol_map( 253 + &mut map, 254 + kiiroo_v2_vibrator::setup::KiirooV2VibratorIdentifierFactory::default(), 255 + ); 256 + add_to_protocol_map( 257 + &mut map, 258 + kiiroo_v21::setup::KiirooV21IdentifierFactory::default(), 259 + ); 260 + add_to_protocol_map( 261 + &mut map, 262 + kiiroo_v21_initialized::setup::KiirooV21InitializedIdentifierFactory::default(), 263 + ); 264 + add_to_protocol_map(&mut map, kizuna::setup::KizunaIdentifierFactory::default()); 265 + add_to_protocol_map( 266 + &mut map, 267 + lelof1s::setup::LeloF1sIdentifierFactory::default(), 268 + ); 269 + add_to_protocol_map( 270 + &mut map, 271 + lelof1sv2::setup::LeloF1sV2IdentifierFactory::default(), 272 + ); 273 + add_to_protocol_map(&mut map, leten::setup::LetenIdentifierFactory::default()); 274 + add_to_protocol_map( 275 + &mut map, 276 + lelo_harmony::setup::LeloHarmonyIdentifierFactory::default(), 277 + ); 278 + add_to_protocol_map( 279 + &mut map, 280 + libo_elle::setup::LiboElleIdentifierFactory::default(), 281 + ); 282 + add_to_protocol_map( 283 + &mut map, 284 + libo_shark::setup::LiboSharkIdentifierFactory::default(), 285 + ); 286 + add_to_protocol_map( 287 + &mut map, 288 + libo_vibes::setup::LiboVibesIdentifierFactory::default(), 289 + ); 290 + add_to_protocol_map( 291 + &mut map, 292 + lioness::setup::LionessIdentifierFactory::default(), 293 + ); 294 + add_to_protocol_map(&mut map, loob::setup::LoobIdentifierFactory::default()); 295 + add_to_protocol_map( 296 + &mut map, 297 + lovehoney_desire::setup::LovehoneyDesireIdentifierFactory::default(), 298 + ); 299 + add_to_protocol_map( 300 + &mut map, 301 + lovedistance::setup::LoveDistanceIdentifierFactory::default(), 302 + ); 303 + // add_to_protocol_map( 304 + // &mut map, 305 + // lovense_connect_service::setup::LovenseConnectServiceIdentifierFactory::default(), 306 + // ); 307 + add_to_protocol_map( 308 + &mut map, 309 + lovenuts::setup::LoveNutsIdentifierFactory::default(), 310 + ); 311 + add_to_protocol_map( 312 + &mut map, 313 + luvmazer::setup::LuvmazerIdentifierFactory::default(), 314 + ); 315 + add_to_protocol_map( 316 + &mut map, 317 + magic_motion_v1::setup::MagicMotionV1IdentifierFactory::default(), 318 + ); 319 + add_to_protocol_map( 320 + &mut map, 321 + magic_motion_v2::setup::MagicMotionV2IdentifierFactory::default(), 322 + ); 323 + add_to_protocol_map( 324 + &mut map, 325 + magic_motion_v3::setup::MagicMotionV3IdentifierFactory::default(), 326 + ); 327 + add_to_protocol_map( 328 + &mut map, 329 + magic_motion_v4::setup::MagicMotionV4IdentifierFactory::default(), 330 + ); 331 + add_to_protocol_map(&mut map, mannuo::setup::ManNuoIdentifierFactory::default()); 332 + add_to_protocol_map(&mut map, maxpro::setup::MaxproIdentifierFactory::default()); 333 + add_to_protocol_map(&mut map, meese::setup::MeeseIdentifierFactory::default()); 334 + add_to_protocol_map( 335 + &mut map, 336 + metaxsire::setup::MetaXSireIdentifierFactory::default(), 337 + ); 338 + add_to_protocol_map( 339 + &mut map, 340 + metaxsire_v2::setup::MetaXSireV2IdentifierFactory::default(), 341 + ); 342 + add_to_protocol_map( 343 + &mut map, 344 + metaxsire_v3::setup::MetaXSireV3IdentifierFactory::default(), 345 + ); 346 + add_to_protocol_map( 347 + &mut map, 348 + metaxsire_v4::setup::MetaXSireV4IdentifierFactory::default(), 349 + ); 350 + add_to_protocol_map( 351 + &mut map, 352 + mizzzee::setup::MizzZeeIdentifierFactory::default(), 353 + ); 354 + add_to_protocol_map( 355 + &mut map, 356 + mizzzee_v2::setup::MizzZeeV2IdentifierFactory::default(), 357 + ); 358 + add_to_protocol_map( 359 + &mut map, 360 + mizzzee_v3::setup::MizzZeeV3IdentifierFactory::default(), 361 + ); 362 + add_to_protocol_map( 363 + &mut map, 364 + monsterpub::setup::MonsterPubIdentifierFactory::default(), 365 + ); 366 + add_to_protocol_map( 367 + &mut map, 368 + motorbunny::setup::MotorbunnyIdentifierFactory::default(), 369 + ); 370 + add_to_protocol_map( 371 + &mut map, 372 + mysteryvibe::setup::MysteryVibeIdentifierFactory::default(), 373 + ); 374 + add_to_protocol_map( 375 + &mut map, 376 + mysteryvibe_v2::setup::MysteryVibeV2IdentifierFactory::default(), 377 + ); 378 + add_to_protocol_map( 379 + &mut map, 380 + nexus_revo::setup::NexusRevoIdentifierFactory::default(), 381 + ); 382 + add_to_protocol_map( 383 + &mut map, 384 + nextlevelracing::setup::NextLevelRacingIdentifierFactory::default(), 385 + ); 386 + add_to_protocol_map( 387 + &mut map, 388 + nintendo_joycon::setup::NintendoJoyconIdentifierFactory::default(), 389 + ); 390 + add_to_protocol_map(&mut map, nobra::setup::NobraIdentifierFactory::default()); 391 + add_to_protocol_map(&mut map, omobo::setup::OmoboIdentifierFactory::default()); 392 + add_to_protocol_map(&mut map, patoo::setup::PatooIdentifierFactory::default()); 393 + add_to_protocol_map( 394 + &mut map, 395 + picobong::setup::PicobongIdentifierFactory::default(), 396 + ); 397 + add_to_protocol_map( 398 + &mut map, 399 + pink_punch::setup::PinkPunchIdentifierFactory::default(), 400 + ); 401 + add_to_protocol_map( 402 + &mut map, 403 + prettylove::setup::PrettyLoveIdentifierFactory::default(), 404 + ); 405 + add_to_protocol_map( 406 + &mut map, 407 + raw_protocol::setup::RawProtocolIdentifierFactory::default(), 408 + ); 409 + add_to_protocol_map(&mut map, realov::setup::RealovIdentifierFactory::default()); 410 + add_to_protocol_map( 411 + &mut map, 412 + sakuraneko::setup::SakuranekoIdentifierFactory::default(), 413 + ); 414 + add_to_protocol_map( 415 + &mut map, 416 + satisfyer::setup::SatisfyerIdentifierFactory::default(), 417 + ); 418 + add_to_protocol_map(&mut map, sensee::setup::SenseeIdentifierFactory::default()); 419 + add_to_protocol_map( 420 + &mut map, 421 + sensee_capsule::setup::SenseeCapsuleIdentifierFactory::default(), 422 + ); 423 + add_to_protocol_map( 424 + &mut map, 425 + sensee_v2::setup::SenseeV2IdentifierFactory::default(), 426 + ); 427 + add_to_protocol_map( 428 + &mut map, 429 + sexverse_lg389::setup::SexverseLG389IdentifierFactory::default(), 430 + ); 431 + add_to_protocol_map(&mut map, serveu::setup::ServeUIdentifierFactory::default()); 432 + //add_to_protocol_map( 433 + // &mut map, 434 + // svakom::svakom_avaneo::setup::SvakomAvaNeoIdentifierFactory::default(), 435 + //); 436 + add_to_protocol_map( 437 + &mut map, 438 + svakom::svakom_alex::setup::SvakomAlexIdentifierFactory::default(), 439 + ); 440 + add_to_protocol_map( 441 + &mut map, 442 + svakom::svakom_alex_v2::setup::SvakomAlexV2IdentifierFactory::default(), 443 + ); 444 + add_to_protocol_map( 445 + &mut map, 446 + svakom::svakom_barnard::setup::SvakomBarnardIdentifierFactory::default(), 447 + ); 448 + add_to_protocol_map( 449 + &mut map, 450 + svakom::svakom_barney::setup::SvakomBarneyIdentifierFactory::default(), 451 + ); 452 + add_to_protocol_map( 453 + &mut map, 454 + svakom::svakom_dice::setup::SvakomDiceIdentifierFactory::default(), 455 + ); 456 + //add_to_protocol_map( 457 + // &mut map, 458 + // svakom::svakom_dt250a::setup::SvakomDT250AIdentifierFactory::default(), 459 + //); 460 + add_to_protocol_map( 461 + &mut map, 462 + svakom::svakom_iker::setup::SvakomIkerIdentifierFactory::default(), 463 + ); 464 + add_to_protocol_map( 465 + &mut map, 466 + svakom::svakom_jordan::setup::SvakomJordanIdentifierFactory::default(), 467 + ); 468 + add_to_protocol_map( 469 + &mut map, 470 + svakom::svakom_pulse::setup::SvakomPulseIdentifierFactory::default(), 471 + ); 472 + add_to_protocol_map( 473 + &mut map, 474 + svakom::svakom_sam::setup::SvakomSamIdentifierFactory::default(), 475 + ); 476 + add_to_protocol_map( 477 + &mut map, 478 + svakom::svakom_sam2::setup::SvakomSam2IdentifierFactory::default(), 479 + ); 480 + //add_to_protocol_map( 481 + // &mut map, 482 + // svakom::svakom_suitcase::setup::SvakomSuitcaseIdentifierFactory::default(), 483 + //); 484 + //add_to_protocol_map( 485 + // &mut map, 486 + // svakom::svakom_tarax::setup::SvakomTaraXIdentifierFactory::default(), 487 + //); 488 + add_to_protocol_map( 489 + &mut map, 490 + svakom::svakom_v1::setup::SvakomV1IdentifierFactory::default(), 491 + ); 492 + add_to_protocol_map( 493 + &mut map, 494 + svakom::svakom_v2::setup::SvakomV2IdentifierFactory::default(), 495 + ); 496 + add_to_protocol_map( 497 + &mut map, 498 + svakom::svakom_v3::setup::SvakomV3IdentifierFactory::default(), 499 + ); 500 + add_to_protocol_map( 501 + &mut map, 502 + svakom::svakom_v4::setup::SvakomV4IdentifierFactory::default(), 503 + ); 504 + add_to_protocol_map( 505 + &mut map, 506 + svakom::svakom_v5::setup::SvakomV5IdentifierFactory::default(), 507 + ); 508 + add_to_protocol_map( 509 + &mut map, 510 + svakom::svakom_v6::setup::SvakomV6IdentifierFactory::default(), 511 + ); 512 + add_to_protocol_map( 513 + &mut map, 514 + synchro::setup::SynchroIdentifierFactory::default(), 515 + ); 516 + add_to_protocol_map(&mut map, tryfun::setup::TryFunIdentifierFactory::default()); 517 + add_to_protocol_map( 518 + &mut map, 519 + tryfun_blackhole::setup::TryFunBlackHoleIdentifierFactory::default(), 520 + ); 521 + add_to_protocol_map( 522 + &mut map, 523 + tryfun_meta2::setup::TryFunMeta2IdentifierFactory::default(), 524 + ); 525 + add_to_protocol_map( 526 + &mut map, 527 + tcode_v03::setup::TCodeV03IdentifierFactory::default(), 528 + ); 529 + add_to_protocol_map( 530 + &mut map, 531 + vibcrafter::setup::VibCrafterIdentifierFactory::default(), 532 + ); 533 + add_to_protocol_map( 534 + &mut map, 535 + vibratissimo::setup::VibratissimoIdentifierFactory::default(), 536 + ); 537 + add_to_protocol_map( 538 + &mut map, 539 + vorze_sa::setup::VorzeSAIdentifierFactory::default(), 540 + ); 541 + add_to_protocol_map(&mut map, wetoy::setup::WeToyIdentifierFactory::default()); 542 + add_to_protocol_map(&mut map, wevibe::setup::WeVibeIdentifierFactory::default()); 543 + add_to_protocol_map( 544 + &mut map, 545 + wevibe8bit::setup::WeVibe8BitIdentifierFactory::default(), 546 + ); 547 + add_to_protocol_map( 548 + &mut map, 549 + wevibe_chorus::setup::WeVibeChorusIdentifierFactory::default(), 550 + ); 551 + add_to_protocol_map(&mut map, xibao::setup::XibaoIdentifierFactory::default()); 552 + add_to_protocol_map(&mut map, xinput::setup::XInputIdentifierFactory::default()); 553 + add_to_protocol_map( 554 + &mut map, 555 + xiuxiuda::setup::XiuxiudaIdentifierFactory::default(), 556 + ); 557 + add_to_protocol_map( 558 + &mut map, 559 + xuanhuan::setup::XuanhuanIdentifierFactory::default(), 560 + ); 561 + add_to_protocol_map( 562 + &mut map, 563 + youcups::setup::YoucupsIdentifierFactory::default(), 564 + ); 565 + add_to_protocol_map(&mut map, youou::setup::YououIdentifierFactory::default()); 566 + add_to_protocol_map(&mut map, zalo::setup::ZaloIdentifierFactory::default()); 567 + add_to_protocol_map( 568 + &mut map, 569 + kgoal_boost::setup::KGoalBoostIdentifierFactory::default(), 570 + ); 571 + map 572 + }