Buttplug sex toy control library
20
fork

Configure Feed

Select the types of activity you want to include in your feed.

chore: Implement replay keepalive strategy

+302 -72
+4
buttplug/src/server/device/protocol/adrienlastic.rs
··· 19 19 pub struct AdrienLastic {} 20 20 21 21 impl ProtocolHandler for AdrienLastic { 22 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 23 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 24 + } 25 + 22 26 fn handle_scalar_vibrate_cmd( 23 27 &self, 24 28 _index: u32,
+4
buttplug/src/server/device/protocol/aneros.rs
··· 19 19 pub struct Aneros {} 20 20 21 21 impl ProtocolHandler for Aneros { 22 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 23 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 24 + } 25 + 22 26 fn handle_scalar_vibrate_cmd( 23 27 &self, 24 28 index: u32,
+4
buttplug/src/server/device/protocol/ankni.rs
··· 77 77 pub struct Ankni {} 78 78 79 79 impl ProtocolHandler for Ankni { 80 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 81 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 82 + } 83 + 80 84 fn handle_scalar_vibrate_cmd( 81 85 &self, 82 86 _index: u32,
+4
buttplug/src/server/device/protocol/buttplug_passthru.rs
··· 22 22 struct ButtplugPassthru {} 23 23 24 24 impl ProtocolHandler for ButtplugPassthru { 25 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 26 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 27 + } 28 + 25 29 fn has_handle_message(&self) -> bool { 26 30 true 27 31 }
+4
buttplug/src/server/device/protocol/cachito.rs
··· 19 19 pub struct Cachito {} 20 20 21 21 impl ProtocolHandler for Cachito { 22 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 23 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 24 + } 25 + 22 26 fn handle_scalar_vibrate_cmd( 23 27 &self, 24 28 index: u32,
+4
buttplug/src/server/device/protocol/cowgirl.rs
··· 22 22 pub struct Cowgirl {} 23 23 24 24 impl ProtocolHandler for Cowgirl { 25 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 26 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 27 + } 28 + 25 29 fn needs_full_command_set(&self) -> bool { 26 30 true 27 31 }
+4
buttplug/src/server/device/protocol/foreo.rs
··· 19 19 pub struct Foreo {} 20 20 21 21 impl ProtocolHandler for Foreo { 22 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 23 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 24 + } 25 + 22 26 fn handle_scalar_vibrate_cmd( 23 27 &self, 24 28 _: u32,
+4
buttplug/src/server/device/protocol/fox.rs
··· 19 19 pub struct Fox {} 20 20 21 21 impl ProtocolHandler for Fox { 22 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 23 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 24 + } 25 + 22 26 fn handle_scalar_vibrate_cmd( 23 27 &self, 24 28 _index: u32,
+4
buttplug/src/server/device/protocol/galaku_pump.rs
··· 30 30 pub struct GalakuPump {} 31 31 32 32 impl ProtocolHandler for GalakuPump { 33 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 34 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 35 + } 36 + 33 37 fn needs_full_command_set(&self) -> bool { 34 38 true 35 39 }
+4
buttplug/src/server/device/protocol/hismith.rs
··· 83 83 pub struct Hismith {} 84 84 85 85 impl ProtocolHandler for Hismith { 86 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 87 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 88 + } 89 + 86 90 fn handle_scalar_oscillate_cmd( 87 91 &self, 88 92 _index: u32,
+4
buttplug/src/server/device/protocol/hismith_mini.rs
··· 96 96 } 97 97 98 98 impl ProtocolHandler for HismithMini { 99 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 100 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 101 + } 102 + 99 103 fn handle_scalar_oscillate_cmd( 100 104 &self, 101 105 _index: u32,
+4 -61
buttplug/src/server/device/protocol/htk_bm.rs
··· 22 22 pub struct HtkBm {} 23 23 24 24 impl ProtocolHandler for HtkBm { 25 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 26 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 27 + } 28 + 25 29 fn handle_scalar_cmd( 26 30 &self, 27 31 cmds: &[Option<(ActuatorType, u32)>], ··· 43 47 Ok(cmd_vec) 44 48 } 45 49 } 46 - 47 - #[cfg(all(test, feature = "server"))] 48 - mod test { 49 - use super::HtkBm; 50 - use crate::{ 51 - core::message::{ActuatorType, Endpoint}, 52 - server::device::{ 53 - hardware::{HardwareCommand, HardwareWriteCmd}, 54 - protocol::ProtocolHandler, 55 - }, 56 - }; 57 - 58 - #[test] 59 - pub fn test_htkbm_protocol() { 60 - let handler = HtkBm {}; 61 - assert_eq!( 62 - handler.handle_scalar_cmd(&vec![ 63 - Some((ActuatorType::Vibrate, 0)), 64 - Some((ActuatorType::Vibrate, 0)) 65 - ]), 66 - Ok(vec![HardwareCommand::Write(HardwareWriteCmd::new( 67 - Endpoint::Tx, 68 - vec![15], 69 - false 70 - ))]) 71 - ); 72 - assert_eq!( 73 - handler.handle_scalar_cmd(&vec![ 74 - Some((ActuatorType::Vibrate, 1)), 75 - Some((ActuatorType::Vibrate, 0)) 76 - ]), 77 - Ok(vec![HardwareCommand::Write(HardwareWriteCmd::new( 78 - Endpoint::Tx, 79 - vec![12], 80 - false 81 - ))]) 82 - ); 83 - assert_eq!( 84 - handler.handle_scalar_cmd(&vec![ 85 - Some((ActuatorType::Vibrate, 0)), 86 - Some((ActuatorType::Vibrate, 1)) 87 - ]), 88 - Ok(vec![HardwareCommand::Write(HardwareWriteCmd::new( 89 - Endpoint::Tx, 90 - vec![13], 91 - false 92 - ))]) 93 - ); 94 - assert_eq!( 95 - handler.handle_scalar_cmd(&vec![ 96 - Some((ActuatorType::Vibrate, 1)), 97 - Some((ActuatorType::Vibrate, 1)) 98 - ]), 99 - Ok(vec![HardwareCommand::Write(HardwareWriteCmd::new( 100 - Endpoint::Tx, 101 - vec![11], 102 - false 103 - ))]) 104 - ); 105 - } 106 - }
+4
buttplug/src/server/device/protocol/jejoue.rs
··· 22 22 pub struct JeJoue {} 23 23 24 24 impl ProtocolHandler for JeJoue { 25 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 26 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 27 + } 28 + 25 29 fn handle_scalar_cmd( 26 30 &self, 27 31 cmds: &[Option<(ActuatorType, u32)>],
+4
buttplug/src/server/device/protocol/kiiroo_v2_vibrator.rs
··· 22 22 pub struct KiirooV2Vibrator {} 23 23 24 24 impl ProtocolHandler for KiirooV2Vibrator { 25 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 26 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 27 + } 28 + 25 29 fn handle_scalar_cmd( 26 30 &self, 27 31 cmds: &[Option<(ActuatorType, u32)>],
+4
buttplug/src/server/device/protocol/kizuna.rs
··· 19 19 pub struct Kizuna {} 20 20 21 21 impl ProtocolHandler for Kizuna { 22 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 23 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 24 + } 25 + 22 26 fn handle_scalar_rotate_cmd( 23 27 &self, 24 28 _index: u32,
+4
buttplug/src/server/device/protocol/lelof1s.rs
··· 52 52 pub struct LeloF1s {} 53 53 54 54 impl ProtocolHandler for LeloF1s { 55 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 56 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 57 + } 58 + 55 59 fn needs_full_command_set(&self) -> bool { 56 60 true 57 61 }
+4
buttplug/src/server/device/protocol/lelof1sv2.rs
··· 101 101 pub struct LeloF1sV2 {} 102 102 103 103 impl ProtocolHandler for LeloF1sV2 { 104 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 105 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 106 + } 107 + 104 108 fn needs_full_command_set(&self) -> bool { 105 109 true 106 110 }
+4
buttplug/src/server/device/protocol/libo_elle.rs
··· 19 19 pub struct LiboElle {} 20 20 21 21 impl ProtocolHandler for LiboElle { 22 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 23 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 24 + } 25 + 22 26 fn handle_scalar_vibrate_cmd( 23 27 &self, 24 28 index: u32,
+4
buttplug/src/server/device/protocol/libo_shark.rs
··· 22 22 pub struct LiboShark {} 23 23 24 24 impl ProtocolHandler for LiboShark { 25 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 26 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 27 + } 28 + 25 29 fn handle_scalar_cmd( 26 30 &self, 27 31 cmds: &[Option<(ActuatorType, u32)>],
+4
buttplug/src/server/device/protocol/libo_vibes.rs
··· 22 22 pub struct LiboVibes {} 23 23 24 24 impl ProtocolHandler for LiboVibes { 25 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 26 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 27 + } 28 + 25 29 fn handle_scalar_cmd( 26 30 &self, 27 31 cmds: &[Option<(ActuatorType, u32)>],
+4
buttplug/src/server/device/protocol/lovedistance.rs
··· 47 47 pub struct LoveDistance {} 48 48 49 49 impl ProtocolHandler for LoveDistance { 50 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 51 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 52 + } 53 + 50 54 fn handle_scalar_vibrate_cmd( 51 55 &self, 52 56 _index: u32,
+4
buttplug/src/server/device/protocol/lovehoney_desire.rs
··· 22 22 pub struct LovehoneyDesire {} 23 23 24 24 impl ProtocolHandler for LovehoneyDesire { 25 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 26 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 27 + } 28 + 25 29 fn needs_full_command_set(&self) -> bool { 26 30 true 27 31 }
+4
buttplug/src/server/device/protocol/lovenuts.rs
··· 19 19 pub struct LoveNuts {} 20 20 21 21 impl ProtocolHandler for LoveNuts { 22 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 23 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 24 + } 25 + 22 26 fn handle_scalar_vibrate_cmd( 23 27 &self, 24 28 _index: u32,
+4
buttplug/src/server/device/protocol/magic_motion_v1.rs
··· 19 19 pub struct MagicMotionV1 {} 20 20 21 21 impl ProtocolHandler for MagicMotionV1 { 22 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 23 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 24 + } 25 + 22 26 fn handle_scalar_vibrate_cmd( 23 27 &self, 24 28 _index: u32,
+4
buttplug/src/server/device/protocol/magic_motion_v2.rs
··· 22 22 pub struct MagicMotionV2 {} 23 23 24 24 impl ProtocolHandler for MagicMotionV2 { 25 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 26 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 27 + } 28 + 25 29 fn needs_full_command_set(&self) -> bool { 26 30 true 27 31 }
+4
buttplug/src/server/device/protocol/magic_motion_v3.rs
··· 19 19 pub struct MagicMotionV3 {} 20 20 21 21 impl ProtocolHandler for MagicMotionV3 { 22 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 23 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 24 + } 25 + 22 26 fn handle_scalar_vibrate_cmd( 23 27 &self, 24 28 _index: u32,
+4
buttplug/src/server/device/protocol/magic_motion_v4.rs
··· 22 22 pub struct MagicMotionV4 {} 23 23 24 24 impl ProtocolHandler for MagicMotionV4 { 25 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 26 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 27 + } 28 + 25 29 fn needs_full_command_set(&self) -> bool { 26 30 true 27 31 }
+4
buttplug/src/server/device/protocol/mannuo.rs
··· 19 19 pub struct ManNuo {} 20 20 21 21 impl ProtocolHandler for ManNuo { 22 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 23 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 24 + } 25 + 22 26 fn handle_scalar_vibrate_cmd( 23 27 &self, 24 28 _index: u32,
+4 -2
buttplug/src/server/device/protocol/maxpro.rs
··· 19 19 pub struct Maxpro {} 20 20 21 21 impl ProtocolHandler for Maxpro { 22 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 23 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 24 + } 25 + 22 26 fn handle_scalar_vibrate_cmd( 23 27 &self, 24 28 _index: u32, ··· 46 50 Ok(vec![HardwareWriteCmd::new(Endpoint::Tx, data, false).into()]) 47 51 } 48 52 } 49 - 50 - // TODO Write some tests! Especially with the weird operational range on this.
+6 -2
buttplug/src/server/device/protocol/meese.rs
··· 19 19 pub struct Meese {} 20 20 21 21 impl ProtocolHandler for Meese { 22 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 23 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 24 + } 25 + 22 26 fn handle_scalar_vibrate_cmd( 23 27 &self, 24 - _index: u32, 28 + index: u32, 25 29 scalar: u32, 26 30 ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 27 31 Ok(vec![HardwareWriteCmd::new( 28 32 Endpoint::Tx, 29 - vec![0x01, 0x80, 0x01 + (_index as u8), (scalar as u8)], 33 + vec![0x01, 0x80, 0x01 + (index as u8), (scalar as u8)], 30 34 true, 31 35 ) 32 36 .into()])
+4
buttplug/src/server/device/protocol/metaxsire.rs
··· 21 21 pub struct MetaXSire {} 22 22 23 23 impl ProtocolHandler for MetaXSire { 24 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 25 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 26 + } 27 + 24 28 fn needs_full_command_set(&self) -> bool { 25 29 true 26 30 }
+4
buttplug/src/server/device/protocol/mizzzee.rs
··· 19 19 pub struct MizzZee {} 20 20 21 21 impl ProtocolHandler for MizzZee { 22 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 23 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 24 + } 25 + 22 26 fn handle_scalar_vibrate_cmd( 23 27 &self, 24 28 _index: u32,
+4
buttplug/src/server/device/protocol/mizzzee_v2.rs
··· 19 19 pub struct MizzZeeV2 {} 20 20 21 21 impl ProtocolHandler for MizzZeeV2 { 22 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 23 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 24 + } 25 + 22 26 fn handle_scalar_vibrate_cmd( 23 27 &self, 24 28 _index: u32,
+19 -4
buttplug/src/server/device/protocol/mod.rs
··· 131 131 /// things alive. Currently this only applies to iOS backgrounding with bluetooth devices, but since 132 132 /// we never know which of our hundreds of supported devices someone might connect, we need context 133 133 /// as to which keepalive strategy to use. 134 + /// 135 + /// When choosing a keepalive strategy for a protocol: 136 + /// 137 + /// - All protocols use NoStrategy by default. For many devices, sending trash will break them in 138 + /// very weird ways and we can't risk that, so we need to know the protocol context. 139 + /// - If the protocol already needs its own keepalive (Satisfyer, Mysteryvibe, etc...), use 140 + /// NoStrategy for now. RepeatLastPacketStrategy could be used, but we'd need per-protocol 141 + /// timeouts at that point. 142 + /// - If the protocol has a command that essentially does nothing to the actuators, set up 143 + /// RepeatPacketStrategy to use that. This is useful for devices that have info commands (like 144 + /// Lovense), ping commands (like The Handy), sensor commands that aren't yet subscribed to output 145 + /// notifications, etc... 146 + /// - For many devices with only scalar actuators, RepeatLastPacketStrategy should work. You just 147 + /// need to make sure the protocol doesn't have a packet counter or something else that will trip 148 + /// if the same packet is replayed multiple times. 149 + /// - For all other devices, use Custom Strategy. This assumes the protocol will have implemented a 150 + /// method to generate a valid packet. 134 151 #[derive(Debug)] 135 152 pub enum ProtocolKeepaliveStrategy { 136 153 /// Do nothing. This is for protocols that already require internal keepalives, like satisfyer, ··· 141 158 /// Repeat whatever the last packet sent was, and send Stop commands until first packet sent. This 142 159 /// will be useful for most devices that purely use scalar commands. 143 160 RepeatLastPacketStrategy, 144 - /// Request battery values as the keep alive. 145 - BatteryStrategy, 146 - /// Protocol implements a custom strategy, use that. 147 - CustomStrategy, 161 + /// Call a specific method on the protocol implementation to generate keepalive packets. 162 + CustomStrategy 148 163 } 149 164 150 165 pub trait ProtocolIdentifierFactory: Send + Sync {
+4
buttplug/src/server/device/protocol/motorbunny.rs
··· 26 26 pub struct Motorbunny {} 27 27 28 28 impl ProtocolHandler for Motorbunny { 29 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 30 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 31 + } 32 + 29 33 fn handle_scalar_vibrate_cmd( 30 34 &self, 31 35 _index: u32,
+4
buttplug/src/server/device/protocol/nobra.rs
··· 46 46 pub struct Nobra {} 47 47 48 48 impl ProtocolHandler for Nobra { 49 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 50 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 51 + } 52 + 49 53 fn handle_scalar_vibrate_cmd( 50 54 &self, 51 55 _index: u32,
+4
buttplug/src/server/device/protocol/patoo.rs
··· 83 83 pub struct Patoo {} 84 84 85 85 impl ProtocolHandler for Patoo { 86 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 87 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 88 + } 89 + 86 90 fn handle_scalar_cmd( 87 91 &self, 88 92 cmds: &[Option<(ActuatorType, u32)>],
+4
buttplug/src/server/device/protocol/picobong.rs
··· 19 19 pub struct Picobong {} 20 20 21 21 impl ProtocolHandler for Picobong { 22 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 23 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 24 + } 25 + 22 26 fn handle_scalar_vibrate_cmd( 23 27 &self, 24 28 _index: u32,
+4
buttplug/src/server/device/protocol/pink_punch.rs
··· 19 19 pub struct PinkPunch {} 20 20 21 21 impl ProtocolHandler for PinkPunch { 22 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 23 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 24 + } 25 + 22 26 fn handle_scalar_vibrate_cmd( 23 27 &self, 24 28 _index: u32,
+4
buttplug/src/server/device/protocol/prettylove.rs
··· 72 72 pub struct PrettyLove {} 73 73 74 74 impl ProtocolHandler for PrettyLove { 75 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 76 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 77 + } 78 + 75 79 fn handle_scalar_vibrate_cmd( 76 80 &self, 77 81 _index: u32,
+4
buttplug/src/server/device/protocol/realov.rs
··· 19 19 pub struct Realov {} 20 20 21 21 impl ProtocolHandler for Realov { 22 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 23 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 24 + } 25 + 22 26 fn handle_scalar_vibrate_cmd( 23 27 &self, 24 28 _index: u32,
+4
buttplug/src/server/device/protocol/sakuraneko.rs
··· 19 19 pub struct Sakuraneko {} 20 20 21 21 impl ProtocolHandler for Sakuraneko { 22 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 23 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 24 + } 25 + 22 26 fn handle_scalar_vibrate_cmd( 23 27 &self, 24 28 _index: u32,
+4
buttplug/src/server/device/protocol/sensee.rs
··· 19 19 pub struct Sensee {} 20 20 21 21 impl ProtocolHandler for Sensee { 22 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 23 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 24 + } 25 + 22 26 fn handle_scalar_vibrate_cmd( 23 27 &self, 24 28 _index: u32,
+4
buttplug/src/server/device/protocol/svakom.rs
··· 19 19 pub struct Svakom {} 20 20 21 21 impl ProtocolHandler for Svakom { 22 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 23 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 24 + } 25 + 22 26 fn handle_scalar_vibrate_cmd( 23 27 &self, 24 28 _index: u32,
+4
buttplug/src/server/device/protocol/svakom_alex.rs
··· 19 19 pub struct SvakomAlex {} 20 20 21 21 impl ProtocolHandler for SvakomAlex { 22 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 23 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 24 + } 25 + 22 26 fn handle_scalar_vibrate_cmd( 23 27 &self, 24 28 _index: u32,
+4
buttplug/src/server/device/protocol/svakom_alex_v2.rs
··· 19 19 pub struct SvakomAlexV2 {} 20 20 21 21 impl ProtocolHandler for SvakomAlexV2 { 22 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 23 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 24 + } 25 + 22 26 fn handle_scalar_vibrate_cmd( 23 27 &self, 24 28 _index: u32,
+4
buttplug/src/server/device/protocol/svakom_barnard.rs
··· 19 19 pub struct SvakomBarnard {} 20 20 21 21 impl ProtocolHandler for SvakomBarnard { 22 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 23 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 24 + } 25 + 22 26 fn handle_scalar_vibrate_cmd( 23 27 &self, 24 28 _index: u32,
+4
buttplug/src/server/device/protocol/svakom_iker.rs
··· 57 57 } 58 58 59 59 impl ProtocolHandler for SvakomIker { 60 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 61 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 62 + } 63 + 60 64 fn handle_scalar_cmd( 61 65 &self, 62 66 cmds: &[Option<(ActuatorType, u32)>],
+4
buttplug/src/server/device/protocol/svakom_pulse.rs
··· 19 19 pub struct SvakomPulse {} 20 20 21 21 impl ProtocolHandler for SvakomPulse { 22 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 23 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 24 + } 25 + 22 26 fn handle_scalar_vibrate_cmd( 23 27 &self, 24 28 _index: u32,
+4
buttplug/src/server/device/protocol/svakom_sam.rs
··· 49 49 pub struct SvakomSam {} 50 50 51 51 impl ProtocolHandler for SvakomSam { 52 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 53 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 54 + } 55 + 52 56 fn handle_scalar_cmd( 53 57 &self, 54 58 cmds: &[Option<(ActuatorType, u32)>],
+4
buttplug/src/server/device/protocol/svakom_v2.rs
··· 19 19 pub struct SvakomV2 {} 20 20 21 21 impl ProtocolHandler for SvakomV2 { 22 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 23 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 24 + } 25 + 22 26 fn handle_scalar_vibrate_cmd( 23 27 &self, 24 28 index: u32,
+4
buttplug/src/server/device/protocol/svakom_v3.rs
··· 19 19 pub struct SvakomV3 {} 20 20 21 21 impl ProtocolHandler for SvakomV3 { 22 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 23 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 24 + } 25 + 22 26 fn handle_scalar_vibrate_cmd( 23 27 &self, 24 28 _index: u32,
+4
buttplug/src/server/device/protocol/svakom_v4.rs
··· 20 20 pub struct SvakomV4 {} 21 21 22 22 impl ProtocolHandler for SvakomV4 { 23 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 24 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 25 + } 26 + 23 27 fn needs_full_command_set(&self) -> bool { 24 28 true 25 29 }
+4
buttplug/src/server/device/protocol/synchro.rs
··· 19 19 pub struct Synchro {} 20 20 21 21 impl ProtocolHandler for Synchro { 22 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 23 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 24 + } 25 + 22 26 fn handle_rotate_cmd( 23 27 &self, 24 28 cmds: &[Option<(u32, bool)>],
+4
buttplug/src/server/device/protocol/tryfun.rs
··· 20 20 pub struct TryFun {} 21 21 22 22 impl ProtocolHandler for TryFun { 23 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 24 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 25 + } 26 + 23 27 fn handle_scalar_oscillate_cmd( 24 28 &self, 25 29 _index: u32,
+4
buttplug/src/server/device/protocol/wetoy.rs
··· 46 46 pub struct WeToy {} 47 47 48 48 impl ProtocolHandler for WeToy { 49 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 50 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 51 + } 52 + 49 53 fn handle_scalar_vibrate_cmd( 50 54 &self, 51 55 _index: u32,
+4
buttplug/src/server/device/protocol/wevibe.rs
··· 61 61 pub struct WeVibe {} 62 62 63 63 impl ProtocolHandler for WeVibe { 64 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 65 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 66 + } 67 + 64 68 fn needs_full_command_set(&self) -> bool { 65 69 true 66 70 }
+4
buttplug/src/server/device/protocol/wevibe8bit.rs
··· 22 22 pub struct WeVibe8Bit {} 23 23 24 24 impl ProtocolHandler for WeVibe8Bit { 25 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 26 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 27 + } 28 + 25 29 fn needs_full_command_set(&self) -> bool { 26 30 true 27 31 }
+4
buttplug/src/server/device/protocol/wevibe_chorus.rs
··· 22 22 pub struct WeVibeChorus {} 23 23 24 24 impl ProtocolHandler for WeVibeChorus { 25 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 26 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 27 + } 28 + 25 29 fn needs_full_command_set(&self) -> bool { 26 30 true 27 31 }
+4
buttplug/src/server/device/protocol/xibao.rs
··· 20 20 pub struct Xibao {} 21 21 22 22 impl ProtocolHandler for Xibao { 23 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 24 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 25 + } 26 + 23 27 fn handle_scalar_oscillate_cmd( 24 28 &self, 25 29 _index: u32,
+4
buttplug/src/server/device/protocol/xiuxiuda.rs
··· 19 19 pub struct Xiuxiuda {} 20 20 21 21 impl ProtocolHandler for Xiuxiuda { 22 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 23 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 24 + } 25 + 22 26 fn handle_scalar_vibrate_cmd( 23 27 &self, 24 28 _index: u32,
+4
buttplug/src/server/device/protocol/youcups.rs
··· 19 19 pub struct Youcups {} 20 20 21 21 impl ProtocolHandler for Youcups { 22 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 23 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 24 + } 25 + 22 26 fn handle_scalar_vibrate_cmd( 23 27 &self, 24 28 _index: u32,
+4
buttplug/src/server/device/protocol/zalo.rs
··· 22 22 pub struct Zalo {} 23 23 24 24 impl ProtocolHandler for Zalo { 25 + fn keepalive_strategy(&self) -> super::ProtocolKeepaliveStrategy { 26 + super::ProtocolKeepaliveStrategy::RepeatLastPacketStrategy 27 + } 28 + 25 29 fn handle_scalar_cmd( 26 30 &self, 27 31 cmds: &[Option<(ActuatorType, u32)>],
+33 -3
buttplug/src/server/device/server_device.rs
··· 51 51 use futures::future::{self, FutureExt}; 52 52 use getset::{Getters, MutGetters, Setters}; 53 53 use serde::{Deserialize, Serialize}; 54 + use tokio::sync::RwLock; 54 55 use tokio_stream::StreamExt; 55 56 56 57 use super::{ 57 58 configuration::{ProtocolDeviceAttributes, ServerDeviceMessageAttributes}, 58 - protocol::{generic_command_manager::GenericCommandManager, ProtocolSpecializer, ProtocolKeepaliveStrategy}, 59 + protocol::{generic_command_manager::GenericCommandManager, ProtocolSpecializer, ProtocolKeepaliveStrategy}, hardware::HardwareWriteCmd, 59 60 }; 60 61 61 62 #[derive(Debug)] ··· 158 159 .initialize(hardware.clone(), &attrs) 159 160 .await?; 160 161 162 + let requires_keepalive = hardware.requires_keepalive(); 163 + let strategy = handler.keepalive_strategy(); 164 + 161 165 // We now have fully initialized hardware, return a server device. 162 - Ok(ServerDevice::new(identifier, handler, hardware, &attrs)) 166 + let device = ServerDevice::new(identifier, handler, hardware, &attrs); 167 + 168 + // If we need a keepalive with a packet replay, set this up via stopping the device on connect. 169 + if requires_keepalive && matches!(strategy, ProtocolKeepaliveStrategy::RepeatLastPacketStrategy) { 170 + if let Err(e) = device.handle_stop_device_cmd().await { 171 + return Err(ButtplugDeviceError::DeviceConnectionError(format!("Error setting up keepalive: {}", e))); 172 + } 173 + } 174 + 175 + Ok(device) 163 176 } 164 177 165 178 pub struct ServerDevice { ··· 170 183 /// Unique identifier for the device 171 184 identifier: ServerDeviceIdentifier, 172 185 raw_subscribed_endpoints: Arc<DashSet<Endpoint>>, 186 + keepalive_packet: Arc<RwLock<Option<HardwareWriteCmd>>> 173 187 } 174 188 impl Debug for ServerDevice { 175 189 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { ··· 203 217 hardware: Arc<Hardware>, 204 218 attributes: &ProtocolDeviceAttributes, 205 219 ) -> Self { 220 + let keepalive_packet = Arc::new(RwLock::new(None)); 221 + let gcm = GenericCommandManager::new(attributes); 206 222 // If we've gotten here, we know our hardware is connected. This means we can start the keepalive if it's required. 207 223 if hardware.requires_keepalive() && !matches!(handler.keepalive_strategy(), ProtocolKeepaliveStrategy::NoStrategy) { 208 224 let hardware = hardware.clone(); 209 225 let strategy = handler.keepalive_strategy(); 226 + let keepalive_packet = keepalive_packet.clone(); 210 227 tokio::spawn(async move { 211 228 // Arbitrary wait time for now. 212 229 let wait_duration = Duration::from_secs(5); ··· 219 236 break; 220 237 } 221 238 } 239 + ProtocolKeepaliveStrategy::RepeatLastPacketStrategy => { 240 + if let Some(packet) = &*keepalive_packet.read().await { 241 + hardware.write_value(&packet); 242 + } 243 + }, 222 244 _ => { 223 245 info!("Protocol keepalive strategy {:?} not implemented, replacing with NoStrategy", strategy); 224 246 } ··· 233 255 234 256 Self { 235 257 identifier, 236 - generic_command_manager: GenericCommandManager::new(attributes), 258 + generic_command_manager: gcm, 237 259 handler, 238 260 hardware, 261 + keepalive_packet, 239 262 attributes: attributes.clone(), 240 263 raw_subscribed_endpoints: Arc::new(DashSet::new()), 241 264 } ··· 511 534 512 535 fn handle_hardware_commands(&self, commands: Vec<HardwareCommand>) -> ButtplugServerResultFuture { 513 536 let hardware = self.hardware.clone(); 537 + let keepalive_type = self.handler.keepalive_strategy(); 538 + let keepalive_packet = self.keepalive_packet.clone(); 514 539 async move { 515 540 // Run commands in order, otherwise we may end up sending out of order. This may take a while, 516 541 // but it's what 99% of protocols expect. If they want something else, they can implement it ··· 520 545 // disconnected. 521 546 for command in commands { 522 547 hardware.parse_message(&command).await?; 548 + if hardware.requires_keepalive() && matches!(keepalive_type, ProtocolKeepaliveStrategy::RepeatLastPacketStrategy) { 549 + if let HardwareCommand::Write(command) = command { 550 + *keepalive_packet.write().await = Some(command); 551 + } 552 + } 523 553 } 524 554 Ok(message::Ok::default().into()) 525 555 }