Buttplug sex toy control library
at dev 312 lines 11 kB view raw
1use buttplug_core::errors::ButtplugDeviceError; 2use dashmap::DashMap; 3use getset::Getters; 4use std::{ 5 collections::HashMap, 6 fmt::{self, Debug}, 7}; 8use uuid::Uuid; 9 10use crate::{ 11 BaseDeviceIdentifier, 12 ButtplugDeviceConfigError, 13 ProtocolCommunicationSpecifier, 14 ServerDeviceDefinition, 15 ServerDeviceDefinitionBuilder, 16 UserDeviceIdentifier, 17}; 18 19#[derive(Default, Clone)] 20pub struct DeviceConfigurationManagerBuilder { 21 base_communication_specifiers: HashMap<String, Vec<ProtocolCommunicationSpecifier>>, 22 user_communication_specifiers: DashMap<String, Vec<ProtocolCommunicationSpecifier>>, 23 base_device_definitions: HashMap<BaseDeviceIdentifier, ServerDeviceDefinition>, 24 user_device_definitions: DashMap<UserDeviceIdentifier, ServerDeviceDefinition>, 25} 26 27impl DeviceConfigurationManagerBuilder { 28 pub fn communication_specifier( 29 &mut self, 30 protocol_name: &str, 31 specifier: &[ProtocolCommunicationSpecifier], 32 ) -> &mut Self { 33 self 34 .base_communication_specifiers 35 .entry(protocol_name.to_owned()) 36 .or_default() 37 .extend(specifier.iter().cloned()); 38 self 39 } 40 41 pub fn base_device_definition( 42 &mut self, 43 identifier: &BaseDeviceIdentifier, 44 features: &ServerDeviceDefinition, 45 ) -> &mut Self { 46 self 47 .base_device_definitions 48 .insert(identifier.clone(), features.clone()); 49 self 50 } 51 52 pub fn user_communication_specifier( 53 &mut self, 54 protocol_name: &str, 55 specifier: &[ProtocolCommunicationSpecifier], 56 ) -> &mut Self { 57 self 58 .user_communication_specifiers 59 .entry(protocol_name.to_owned()) 60 .or_default() 61 .extend(specifier.iter().cloned()); 62 self 63 } 64 65 pub fn user_device_definition( 66 &mut self, 67 identifier: &UserDeviceIdentifier, 68 device_definition: &ServerDeviceDefinition, 69 ) -> Result<&mut Self, ButtplugDeviceConfigError> { 70 if self 71 .base_device_definitions 72 .iter() 73 .any(|(_, x)| x.id() == device_definition.base_id().unwrap_or_default()) 74 { 75 self 76 .user_device_definitions 77 .insert(identifier.clone(), device_definition.clone()); 78 Ok(self) 79 } else { 80 error!( 81 "Cannot find protocol with base id {:?} for user id {}", 82 device_definition.base_id(), 83 device_definition.id() 84 ); 85 Err(ButtplugDeviceConfigError::BaseIdNotFound( 86 device_definition.id(), 87 )) 88 } 89 } 90 91 pub fn finish(&mut self) -> Result<DeviceConfigurationManager, ButtplugDeviceError> { 92 // Build and validate the protocol attributes tree. 93 let mut attribute_tree_map = HashMap::new(); 94 95 // Add all the defaults first, they won't have parent attributes. 96 for (ident, attr) in &self.base_device_definitions { 97 attribute_tree_map.insert(ident.clone(), attr.clone()); 98 } 99 100 let user_attribute_tree_map = DashMap::new(); 101 // Finally, add in user configurations, which will have an address. 102 for kv in &self.user_device_definitions { 103 user_attribute_tree_map.insert(kv.key().clone(), kv.value().clone()); 104 } 105 106 Ok(DeviceConfigurationManager { 107 base_communication_specifiers: self.base_communication_specifiers.clone(), 108 user_communication_specifiers: self.user_communication_specifiers.clone(), 109 base_device_definitions: attribute_tree_map, 110 user_device_definitions: user_attribute_tree_map, 111 //protocol_map, 112 }) 113 } 114} 115 116/// Correlates information about protocols and which devices they support. 117/// 118/// The [DeviceConfigurationManager] handles stores information about which device protocols the 119/// library supports, as well as which devices can use those protocols. When a 120/// [DeviceCommunicationManager](crate::server::device::communication_manager) finds a device during scanning, 121/// device information is given to the [DeviceConfigurationManager] to decide whether Buttplug 122/// should try to connect to and communicate with the device. 123/// 124/// Assuming the device is supported by the library, the [DeviceConfigurationManager] also stores 125/// information about what commands can be sent to the device (Vibrate, Rotate, etc...), and the 126/// parameters for those commands (number of power levels, stroke distances, etc...). 127#[derive(Getters)] 128#[getset(get = "pub(crate)")] 129pub struct DeviceConfigurationManager { 130 /// Communication specifiers from the base device config, mapped from protocol name to vector of 131 /// specifiers. Should not change/update during a session. 132 #[getset(get = "pub")] 133 base_communication_specifiers: HashMap<String, Vec<ProtocolCommunicationSpecifier>>, 134 /// Device definitions from the base device config. Should not change/update during a session. 135 base_device_definitions: HashMap<BaseDeviceIdentifier, ServerDeviceDefinition>, 136 /// Communication specifiers provided by the user, mapped from protocol name to vector of 137 /// specifiers. Loaded at session start, may change over life of session. 138 #[getset(get = "pub")] 139 user_communication_specifiers: DashMap<String, Vec<ProtocolCommunicationSpecifier>>, 140 /// Device definitions from the user device config. Loaded at session start, may change over life 141 /// of session. 142 #[getset(get = "pub")] 143 user_device_definitions: DashMap<UserDeviceIdentifier, ServerDeviceDefinition>, 144} 145 146impl Debug for DeviceConfigurationManager { 147 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 148 f.debug_struct("DeviceConfigurationManager").finish() 149 } 150} 151 152impl Default for DeviceConfigurationManager { 153 fn default() -> Self { 154 // Unwrap allowed here because we assume our built in device config will 155 // always work. System won't pass tests or possibly even build otherwise. 156 DeviceConfigurationManagerBuilder::default() 157 .finish() 158 .expect("Default creation of a DCM should always work.") 159 } 160} 161 162impl DeviceConfigurationManager { 163 pub fn add_user_communication_specifier( 164 &self, 165 protocol: &str, 166 specifier: &ProtocolCommunicationSpecifier, 167 ) -> Result<(), ButtplugDeviceError> { 168 //self.protocol_map.contains_key(protocol); 169 self 170 .user_communication_specifiers 171 .entry(protocol.to_owned()) 172 .or_default() 173 .push(specifier.clone()); 174 Ok(()) 175 } 176 177 pub fn remove_user_communication_specifier( 178 &self, 179 protocol: &str, 180 specifier: &ProtocolCommunicationSpecifier, 181 ) { 182 if let Some(mut specifiers) = self.user_communication_specifiers.get_mut(protocol) { 183 let specifier_vec = specifiers.value_mut(); 184 *specifier_vec = specifier_vec 185 .iter() 186 .filter(|s| *specifier != **s) 187 .cloned() 188 .collect(); 189 } 190 } 191 192 pub fn add_user_device_definition( 193 &self, 194 identifier: &UserDeviceIdentifier, 195 definition: &ServerDeviceDefinition, 196 ) { 197 // TODO we should actually check validity of the definition we're adding here, i.e. does it have 198 // a base id, is that ID in our base selections, etc... 199 self 200 .user_device_definitions 201 .insert(identifier.clone(), definition.clone()); 202 } 203 204 pub fn remove_user_device_definition(&self, identifier: &UserDeviceIdentifier) { 205 self.user_device_definitions.remove(identifier); 206 } 207 208 pub fn address_allowed(&self, address: &str) -> bool { 209 // Make sure the device isn't on the deny list 210 if self 211 .user_device_definitions 212 .iter() 213 .any(|kv| kv.key().address() == address && kv.value().deny()) 214 { 215 // If device is outright denied, deny 216 info!( 217 "Device {} denied by configuration, not connecting.", 218 address 219 ); 220 false 221 } else if self 222 .user_device_definitions 223 .iter() 224 .any(|kv| kv.value().allow()) 225 && !self 226 .user_device_definitions 227 .iter() 228 .any(|kv| kv.key().address() == address && kv.value().allow()) 229 { 230 // If device is not on allow list and allow list isn't empty, deny 231 info!( 232 "Device {} not on allow list and allow list not empty, not connecting.", 233 address 234 ); 235 false 236 } else { 237 true 238 } 239 } 240 241 fn device_index(&self, identifier: &UserDeviceIdentifier) -> u32 { 242 // See if we have a reserved or reusable device index here. 243 if let Some(config) = self.user_device_definitions.get(identifier) { 244 let index = config.index(); 245 debug!("Found index {index} for device {identifier:?}"); 246 return index; 247 } 248 249 let current_indexes: Vec<u32> = self 250 .user_device_definitions 251 .iter() 252 .map(|x| x.index()) 253 .collect(); 254 255 // Someone is gonna make a max device index in their config file just to fuck with me, therefore 256 // we don't do "max + 1", we fill in holes (lol) in sequences. To whomever has 4 billion sex toys: 257 // sorry your index finding for new devices is slow and takes 16GB of allocation every time we 258 // want to search the index space. 259 260 let mut index = 0; 261 while current_indexes.contains(&index) { 262 index += 1; 263 } 264 debug!("Generating and assigning index {index:?} for device {identifier:?}"); 265 index 266 } 267 268 pub fn device_definition( 269 &self, 270 identifier: &UserDeviceIdentifier, 271 ) -> Option<ServerDeviceDefinition> { 272 let features = if let Some(definition) = self.user_device_definitions.get(identifier) { 273 debug!("User device config found for {:?}", identifier); 274 definition.clone() 275 } else if let Some(definition) = self.base_device_definitions.get(&BaseDeviceIdentifier::new( 276 identifier.protocol(), 277 identifier.identifier(), 278 )) { 279 debug!( 280 "Protocol + Identifier device config found for {:?}, creating new user device from configuration", 281 identifier 282 ); 283 let mut builder = ServerDeviceDefinitionBuilder::from_base(definition, Uuid::new_v4(), true); 284 builder.index(self.device_index(identifier)).finish() 285 } else if let Some(definition) = self 286 .base_device_definitions 287 .get(&BaseDeviceIdentifier::new(identifier.protocol(), &None)) 288 { 289 debug!( 290 "Protocol device config found for {:?}, creating new user device from protocol defaults", 291 identifier 292 ); 293 let mut builder = ServerDeviceDefinitionBuilder::from_base(definition, Uuid::new_v4(), true); 294 builder.index(self.device_index(identifier)).finish() 295 } else { 296 return None; 297 }; 298 299 // If this is a new device, it needs to be added to the user device definition map. 300 // 301 // Device definitions are looked up before we fully initialize a device, mostly for algorithm 302 // preparation. There is a very small chance we may save the device config then error out when 303 // we connect to the device, but we'll assume we may connect successfully later. 304 if self.user_device_definitions.get(identifier).is_none() { 305 self 306 .user_device_definitions 307 .insert(identifier.clone(), features.clone()); 308 } 309 310 Some(features) 311 } 312}