Buttplug sex toy control library

chore: Split message attrs into client/server versions

Instead of requiring the only message attributes class to conform to
what both the client AND server need, split attributes into server
(which will handle configuration) and client (which is what we'll fly
over the protocol).

+434 -172
+3 -3
buttplug/src/client/device.rs
··· 24 ButtplugCurrentSpecServerMessage, 25 ButtplugDeviceMessageType, 26 ButtplugMessage, 27 - DeviceMessageAttributes, 28 DeviceMessageInfo, 29 Endpoint, 30 LinearCmd, ··· 159 /// Map of messages the device can take, along with the attributes of those 160 /// messages. 161 #[getset(get = "pub")] 162 - message_attributes: DeviceMessageAttributes, 163 /// Sends commands from the [ButtplugClientDevice] instance to the 164 /// [ButtplugClient][super::ButtplugClient]'s event loop, which will then send 165 /// the message on to the [ButtplugServer][crate::server::ButtplugServer] ··· 192 pub(super) fn new( 193 name: &str, 194 index: u32, 195 - message_attributes: &DeviceMessageAttributes, 196 message_sender: broadcast::Sender<ButtplugClientRequest>, 197 ) -> Self { 198 info!(
··· 24 ButtplugCurrentSpecServerMessage, 25 ButtplugDeviceMessageType, 26 ButtplugMessage, 27 + ClientDeviceMessageAttributes, 28 DeviceMessageInfo, 29 Endpoint, 30 LinearCmd, ··· 159 /// Map of messages the device can take, along with the attributes of those 160 /// messages. 161 #[getset(get = "pub")] 162 + message_attributes: ClientDeviceMessageAttributes, 163 /// Sends commands from the [ButtplugClientDevice] instance to the 164 /// [ButtplugClient][super::ButtplugClient]'s event loop, which will then send 165 /// the message on to the [ButtplugServer][crate::server::ButtplugServer] ··· 192 pub(super) fn new( 193 name: &str, 194 index: u32, 195 + message_attributes: &ClientDeviceMessageAttributes, 196 message_sender: broadcast::Sender<ButtplugClientRequest>, 197 ) -> Self { 198 info!(
+4 -4
buttplug/src/core/messages/device_added.rs
··· 29 device_name: String, 30 #[cfg_attr(feature = "serialize-json", serde(rename = "DeviceMessages"))] 31 #[getset(get = "pub")] 32 - device_messages: DeviceMessageAttributes, 33 } 34 35 impl DeviceAdded { 36 pub fn new( 37 device_index: u32, 38 device_name: &str, 39 - device_messages: &DeviceMessageAttributes, 40 ) -> Self { 41 Self { 42 id: 0, ··· 66 device_name: String, 67 #[cfg_attr(feature = "serialize-json", serde(rename = "DeviceMessages"))] 68 #[getset(get = "pub")] 69 - device_messages: DeviceMessageAttributesV2, 70 } 71 72 impl From<DeviceAdded> for DeviceAddedV2 { ··· 103 device_name: String, 104 #[cfg_attr(feature = "serialize-json", serde(rename = "DeviceMessages"))] 105 #[getset(get = "pub")] 106 - device_messages: DeviceMessageAttributesV1, 107 } 108 109 impl From<DeviceAdded> for DeviceAddedV1 {
··· 29 device_name: String, 30 #[cfg_attr(feature = "serialize-json", serde(rename = "DeviceMessages"))] 31 #[getset(get = "pub")] 32 + device_messages: ClientDeviceMessageAttributes, 33 } 34 35 impl DeviceAdded { 36 pub fn new( 37 device_index: u32, 38 device_name: &str, 39 + device_messages: &ClientDeviceMessageAttributes, 40 ) -> Self { 41 Self { 42 id: 0, ··· 66 device_name: String, 67 #[cfg_attr(feature = "serialize-json", serde(rename = "DeviceMessages"))] 68 #[getset(get = "pub")] 69 + device_messages: ClientDeviceMessageAttributesV2, 70 } 71 72 impl From<DeviceAdded> for DeviceAddedV2 { ··· 103 device_name: String, 104 #[cfg_attr(feature = "serialize-json", serde(rename = "DeviceMessages"))] 105 #[getset(get = "pub")] 106 + device_messages: ClientDeviceMessageAttributesV1, 107 } 108 109 impl From<DeviceAdded> for DeviceAddedV1 {
+4 -4
buttplug/src/core/messages/device_message_info.rs
··· 22 device_name: String, 23 #[cfg_attr(feature = "serialize-json", serde(rename = "DeviceMessages"))] 24 #[getset(get = "pub")] 25 - device_messages: DeviceMessageAttributes, 26 } 27 28 impl DeviceMessageInfo { 29 pub fn new( 30 device_index: u32, 31 device_name: &str, 32 - device_messages: DeviceMessageAttributes, 33 ) -> Self { 34 Self { 35 device_index, ··· 60 device_name: String, 61 #[cfg_attr(feature = "serialize-json", serde(rename = "DeviceMessages"))] 62 #[getset(get = "pub")] 63 - device_messages: DeviceMessageAttributesV2, 64 } 65 66 impl From<DeviceAdded> for DeviceMessageInfoV2 { ··· 103 device_name: String, 104 #[cfg_attr(feature = "serialize-json", serde(rename = "DeviceMessages"))] 105 #[getset(get = "pub")] 106 - device_messages: DeviceMessageAttributesV1, 107 } 108 109 impl From<DeviceAdded> for DeviceMessageInfoV1 {
··· 22 device_name: String, 23 #[cfg_attr(feature = "serialize-json", serde(rename = "DeviceMessages"))] 24 #[getset(get = "pub")] 25 + device_messages: ClientDeviceMessageAttributes, 26 } 27 28 impl DeviceMessageInfo { 29 pub fn new( 30 device_index: u32, 31 device_name: &str, 32 + device_messages: ClientDeviceMessageAttributes, 33 ) -> Self { 34 Self { 35 device_index, ··· 60 device_name: String, 61 #[cfg_attr(feature = "serialize-json", serde(rename = "DeviceMessages"))] 62 #[getset(get = "pub")] 63 + device_messages: ClientDeviceMessageAttributesV2, 64 } 65 66 impl From<DeviceAdded> for DeviceMessageInfoV2 { ··· 103 device_name: String, 104 #[cfg_attr(feature = "serialize-json", serde(rename = "DeviceMessages"))] 105 #[getset(get = "pub")] 106 + device_messages: ClientDeviceMessageAttributesV1, 107 } 108 109 impl From<DeviceAdded> for DeviceMessageInfoV1 {
+44 -119
buttplug/src/core/messages/message_attributes.rs buttplug/src/core/messages/client_device_message_attributes.rs
··· 37 // Gyro, 38 } 39 40 - // Unlike other message components, MessageAttributes is always turned on for 41 - // serialization, because it's used by device configuration files also. 42 #[derive( 43 - Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, Getters, MutGetters, Setters, 44 )] 45 - pub struct DeviceMessageAttributes { 46 // Generic commands 47 #[getset(get = "pub", get_mut = "pub")] 48 #[serde(rename = "ScalarCmd")] 49 #[serde(skip_serializing_if = "Option::is_none")] 50 - scalar_cmd: Option<Vec<GenericDeviceMessageAttributes>>, 51 #[getset(get = "pub", get_mut = "pub")] 52 #[serde(rename = "RotateCmd")] 53 #[serde(skip_serializing_if = "Option::is_none")] 54 - rotate_cmd: Option<Vec<GenericDeviceMessageAttributes>>, 55 #[getset(get = "pub", get_mut = "pub")] 56 #[serde(rename = "LinearCmd")] 57 #[serde(skip_serializing_if = "Option::is_none")] 58 - linear_cmd: Option<Vec<GenericDeviceMessageAttributes>>, 59 60 // Sensor Messages 61 #[getset(get = "pub")] ··· 103 vorze_a10_cyclone_cmd: Option<NullDeviceMessageAttributes>, 104 } 105 106 - impl DeviceMessageAttributes { 107 pub fn raw_unsubscribe_cmd(&self) -> &Option<RawDeviceMessageAttributes> { 108 self.raw_subscribe_cmd() 109 } ··· 151 ButtplugDeviceMessageType::LovenseCmd => false, 152 } 153 } 154 - 155 - pub fn merge(&self, child: &DeviceMessageAttributes) -> DeviceMessageAttributes { 156 - Self { 157 - rotate_cmd: child 158 - .rotate_cmd() 159 - .clone() 160 - .or_else(|| self.rotate_cmd().clone()), 161 - linear_cmd: child 162 - .linear_cmd() 163 - .clone() 164 - .or_else(|| self.linear_cmd().clone()), 165 - scalar_cmd: child 166 - .scalar_cmd() 167 - .clone() 168 - .or_else(|| self.scalar_cmd().clone()), 169 - sensor_read_cmd: child 170 - .sensor_read_cmd() 171 - .clone() 172 - .or_else(|| self.sensor_read_cmd().clone()), 173 - sensor_subscribe_cmd: child 174 - .sensor_subscribe_cmd() 175 - .clone() 176 - .or_else(|| self.sensor_subscribe_cmd().clone()), 177 - stop_device_cmd: NullDeviceMessageAttributes::default(), 178 - raw_read_cmd: child 179 - .raw_read_cmd() 180 - .clone() 181 - .or_else(|| self.raw_read_cmd().clone()), 182 - raw_write_cmd: child 183 - .raw_write_cmd() 184 - .clone() 185 - .or_else(|| self.raw_write_cmd().clone()), 186 - raw_subscribe_cmd: child 187 - .raw_subscribe_cmd() 188 - .clone() 189 - .or_else(|| self.raw_subscribe_cmd().clone()), 190 - fleshlight_launch_fw12_cmd: child 191 - .fleshlight_launch_fw12_cmd() 192 - .clone() 193 - .or_else(|| self.fleshlight_launch_fw12_cmd().clone()), 194 - vorze_a10_cyclone_cmd: child 195 - .vorze_a10_cyclone_cmd() 196 - .clone() 197 - .or_else(|| self.vorze_a10_cyclone_cmd().clone()), 198 - } 199 - } 200 201 - pub fn add_raw_messages(&mut self, endpoints: &[Endpoint]) { 202 - let raw_attrs = RawDeviceMessageAttributes { 203 - endpoints: endpoints.clone().to_vec(), 204 - }; 205 - self.raw_read_cmd = Some(raw_attrs.clone()); 206 - self.raw_write_cmd = Some(raw_attrs.clone()); 207 - self.raw_subscribe_cmd = Some(raw_attrs.clone()); 208 - } 209 - } 210 211 #[derive(Default)] 212 - pub struct DeviceMessageAttributesBuilder { 213 - attrs: DeviceMessageAttributes, 214 } 215 216 - impl DeviceMessageAttributesBuilder { 217 - pub fn scalar_cmd(&mut self, attrs: &Vec<GenericDeviceMessageAttributes>) -> &Self { 218 self.attrs.scalar_cmd = Some(attrs.clone()); 219 self 220 } 221 222 - pub fn rotate_cmd(&mut self, attrs: &Vec<GenericDeviceMessageAttributes>) -> &Self { 223 self.attrs.rotate_cmd = Some(attrs.clone()); 224 self 225 } 226 227 - pub fn linear_cmd(&mut self, attrs: &Vec<GenericDeviceMessageAttributes>) -> &Self { 228 self.attrs.linear_cmd = Some(attrs.clone()); 229 self 230 } ··· 254 self 255 } 256 257 - pub fn finish(&self) -> DeviceMessageAttributes { 258 self.attrs.clone() 259 } 260 } 261 262 #[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] 263 pub struct NullDeviceMessageAttributes {} 264 ··· 267 } 268 269 #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Getters, Setters)] 270 - pub struct GenericDeviceMessageAttributes { 271 #[getset(get = "pub")] 272 #[serde(rename = "FeatureDescriptor")] 273 #[serde(default = "unspecified_feature")] ··· 275 #[getset(get = "pub")] 276 #[serde(rename = "ActuatorType")] 277 actuator_type: ActuatorType, 278 - #[serde(rename = "StepRange")] 279 - #[serde(skip_serializing)] 280 - #[getset(get = "pub", set = "pub")] 281 - step_range: RangeInclusive<u32>, 282 } 283 284 - impl GenericDeviceMessageAttributes { 285 pub fn new( 286 feature_descriptor: &str, 287 - step_range: &RangeInclusive<u32>, 288 actuator_type: ActuatorType, 289 ) -> Self { 290 Self { 291 feature_descriptor: feature_descriptor.to_owned(), 292 actuator_type, 293 - step_range: step_range.clone(), 294 } 295 - } 296 - 297 - pub fn step_count(&self) -> u32 { 298 - self.step_range.end() - self.step_range.start() 299 } 300 301 pub fn is_valid( 302 &self, 303 message_type: &ButtplugDeviceMessageType, 304 ) -> Result<(), ButtplugDeviceError> { 305 - if self.step_range.is_empty() { 306 - Err(ButtplugDeviceError::DeviceConfigurationError(format!( 307 - "Step range out of order for {}, must be start <= x <= end.", 308 - message_type 309 - ))) 310 - } else { 311 - Ok(()) 312 - } 313 } 314 } 315 ··· 350 */ 351 352 #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Getters, Setters)] 353 - pub struct DeviceMessageAttributesV2 { 354 // Generic commands 355 #[getset(get = "pub")] 356 #[serde(rename = "VibrateCmd")] ··· 405 vorze_a10_cyclone_cmd: Option<NullDeviceMessageAttributes>, 406 } 407 408 - impl From<DeviceMessageAttributes> for DeviceMessageAttributesV2 { 409 - fn from(other: DeviceMessageAttributes) -> Self { 410 Self { 411 vibrate_cmd: other 412 .scalar_cmd() ··· 469 } 470 471 impl GenericDeviceMessageAttributesV2 { 472 - pub fn vibrate_cmd_from_scalar_cmd(attributes_vec: Vec<GenericDeviceMessageAttributes>) -> Self { 473 let mut feature_count = 0u32; 474 let mut step_count = vec![]; 475 for attr in attributes_vec { 476 if *attr.actuator_type() == ActuatorType::Vibrate { 477 feature_count += 1; 478 - step_count.push(attr.step_count()); 479 } 480 } 481 Self { 482 feature_count, 483 - step_count, 484 } 485 } 486 } 487 488 - impl From<Vec<GenericDeviceMessageAttributes>> for GenericDeviceMessageAttributesV2 { 489 - fn from(attributes_vec: Vec<GenericDeviceMessageAttributes>) -> Self { 490 Self { 491 feature_count: attributes_vec.len() as u32, 492 - step_count: attributes_vec.iter().map(|x| x.step_count()).collect(), 493 } 494 } 495 } 496 497 #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Getters, Setters)] 498 - pub struct DeviceMessageAttributesV1 { 499 // Generic commands 500 #[getset(get = "pub")] 501 #[serde(rename = "VibrateCmd")] ··· 526 vorze_a10_cyclone_cmd: Option<NullDeviceMessageAttributes>, 527 } 528 529 - impl From<DeviceMessageAttributesV2> for DeviceMessageAttributesV1 { 530 - fn from(other: DeviceMessageAttributesV2) -> Self { 531 Self { 532 vibrate_cmd: other 533 .vibrate_cmd() ··· 566 } 567 } 568 } 569 - 570 - #[cfg(test)] 571 - mod test { 572 - use super::*; 573 - 574 - #[test] 575 - pub fn test_step_count_calculation() { 576 - let mut vibrate_attributes = GenericDeviceMessageAttributes::new( 577 - "test", 578 - &RangeInclusive::new(0, 10), 579 - ActuatorType::Vibrate, 580 - ); 581 - assert_eq!(vibrate_attributes.step_count(), 10); 582 - vibrate_attributes.set_step_range(RangeInclusive::new(3u32, 7)); 583 - assert_eq!(vibrate_attributes.step_count(), 4); 584 - } 585 - }
··· 37 // Gyro, 38 } 39 40 + // This will look almost exactly like ServerDeviceMessageAttributes. However, it will only contain 41 + // information we want the client to know, i.e. step counts versus specific step ranges. This is 42 + // what will be sent to the client as part of DeviceAdded/DeviceList messages. It should not be used 43 + // for outside configuration/serialization, rather it should be a subset of that information. 44 + // 45 + // For many messages, client and server configurations may be exactly the same. If they are not, 46 + // then we denote this by prefixing the type with Client/Server. Server attributes will usually be 47 + // hosted in the server/device/configuration module. 48 #[derive( 49 + Clone, Debug, Default, PartialEq, Eq, Getters, MutGetters, Setters, 50 )] 51 + #[cfg_attr(feature = "serialize-json", derive(Serialize, Deserialize))] 52 + pub struct ClientDeviceMessageAttributes { 53 // Generic commands 54 #[getset(get = "pub", get_mut = "pub")] 55 #[serde(rename = "ScalarCmd")] 56 #[serde(skip_serializing_if = "Option::is_none")] 57 + scalar_cmd: Option<Vec<ClientGenericDeviceMessageAttributes>>, 58 #[getset(get = "pub", get_mut = "pub")] 59 #[serde(rename = "RotateCmd")] 60 #[serde(skip_serializing_if = "Option::is_none")] 61 + rotate_cmd: Option<Vec<ClientGenericDeviceMessageAttributes>>, 62 #[getset(get = "pub", get_mut = "pub")] 63 #[serde(rename = "LinearCmd")] 64 #[serde(skip_serializing_if = "Option::is_none")] 65 + linear_cmd: Option<Vec<ClientGenericDeviceMessageAttributes>>, 66 67 // Sensor Messages 68 #[getset(get = "pub")] ··· 110 vorze_a10_cyclone_cmd: Option<NullDeviceMessageAttributes>, 111 } 112 113 + impl ClientDeviceMessageAttributes { 114 pub fn raw_unsubscribe_cmd(&self) -> &Option<RawDeviceMessageAttributes> { 115 self.raw_subscribe_cmd() 116 } ··· 158 ButtplugDeviceMessageType::LovenseCmd => false, 159 } 160 } 161 + } 162 163 164 #[derive(Default)] 165 + pub struct ClientDeviceMessageAttributesBuilder { 166 + attrs: ClientDeviceMessageAttributes, 167 } 168 169 + impl ClientDeviceMessageAttributesBuilder { 170 + pub fn scalar_cmd(&mut self, attrs: &Vec<ClientGenericDeviceMessageAttributes>) -> &Self { 171 self.attrs.scalar_cmd = Some(attrs.clone()); 172 self 173 } 174 175 + pub fn rotate_cmd(&mut self, attrs: &Vec<ClientGenericDeviceMessageAttributes>) -> &Self { 176 self.attrs.rotate_cmd = Some(attrs.clone()); 177 self 178 } 179 180 + pub fn linear_cmd(&mut self, attrs: &Vec<ClientGenericDeviceMessageAttributes>) -> &Self { 181 self.attrs.linear_cmd = Some(attrs.clone()); 182 self 183 } ··· 207 self 208 } 209 210 + pub fn finish(&self) -> ClientDeviceMessageAttributes { 211 self.attrs.clone() 212 } 213 } 214 215 + 216 #[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] 217 pub struct NullDeviceMessageAttributes {} 218 ··· 221 } 222 223 #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Getters, Setters)] 224 + pub struct ClientGenericDeviceMessageAttributes { 225 #[getset(get = "pub")] 226 #[serde(rename = "FeatureDescriptor")] 227 #[serde(default = "unspecified_feature")] ··· 229 #[getset(get = "pub")] 230 #[serde(rename = "ActuatorType")] 231 actuator_type: ActuatorType, 232 + #[serde(rename = "StepCount")] 233 + #[getset(get = "pub")] 234 + step_count: u32 235 } 236 237 + impl ClientGenericDeviceMessageAttributes { 238 pub fn new( 239 feature_descriptor: &str, 240 + step_count: u32, 241 actuator_type: ActuatorType, 242 ) -> Self { 243 Self { 244 feature_descriptor: feature_descriptor.to_owned(), 245 actuator_type, 246 + step_count 247 } 248 } 249 250 pub fn is_valid( 251 &self, 252 message_type: &ButtplugDeviceMessageType, 253 ) -> Result<(), ButtplugDeviceError> { 254 + Ok(()) 255 } 256 } 257 ··· 292 */ 293 294 #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Getters, Setters)] 295 + pub struct ClientDeviceMessageAttributesV2 { 296 // Generic commands 297 #[getset(get = "pub")] 298 #[serde(rename = "VibrateCmd")] ··· 347 vorze_a10_cyclone_cmd: Option<NullDeviceMessageAttributes>, 348 } 349 350 + impl From<ClientDeviceMessageAttributes> for ClientDeviceMessageAttributesV2 { 351 + fn from(other: ClientDeviceMessageAttributes) -> Self { 352 Self { 353 vibrate_cmd: other 354 .scalar_cmd() ··· 411 } 412 413 impl GenericDeviceMessageAttributesV2 { 414 + pub fn vibrate_cmd_from_scalar_cmd(attributes_vec: Vec<ClientGenericDeviceMessageAttributes>) -> Self { 415 let mut feature_count = 0u32; 416 let mut step_count = vec![]; 417 for attr in attributes_vec { 418 if *attr.actuator_type() == ActuatorType::Vibrate { 419 feature_count += 1; 420 + step_count.push(*attr.step_count()); 421 } 422 } 423 Self { 424 feature_count, 425 + step_count 426 } 427 } 428 } 429 430 + impl From<Vec<ClientGenericDeviceMessageAttributes>> for GenericDeviceMessageAttributesV2 { 431 + fn from(attributes_vec: Vec<ClientGenericDeviceMessageAttributes>) -> Self { 432 Self { 433 feature_count: attributes_vec.len() as u32, 434 + step_count: attributes_vec.iter().map(|x| *x.step_count()).collect(), 435 } 436 } 437 } 438 439 #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Getters, Setters)] 440 + pub struct ClientDeviceMessageAttributesV1 { 441 // Generic commands 442 #[getset(get = "pub")] 443 #[serde(rename = "VibrateCmd")] ··· 468 vorze_a10_cyclone_cmd: Option<NullDeviceMessageAttributes>, 469 } 470 471 + impl From<ClientDeviceMessageAttributesV2> for ClientDeviceMessageAttributesV1 { 472 + fn from(other: ClientDeviceMessageAttributesV2) -> Self { 473 Self { 474 vibrate_cmd: other 475 .vibrate_cmd() ··· 508 } 509 } 510 }
+13 -11
buttplug/src/core/messages/mod.rs
··· 27 mod log; 28 mod log_level; 29 mod lovense_cmd; 30 - mod message_attributes; 31 mod ok; 32 mod ping; 33 mod raw_read_cmd; ··· 72 pub use linear_cmd::{LinearCmd, VectorSubcommand}; 73 pub use log_level::LogLevel; 74 pub use lovense_cmd::LovenseCmd; 75 - pub use message_attributes::{ 76 ActuatorType, 77 - DeviceMessageAttributes, 78 - DeviceMessageAttributesBuilder, 79 - DeviceMessageAttributesV1, 80 - DeviceMessageAttributesV2, 81 - GenericDeviceMessageAttributes, 82 SensorDeviceMessageAttributes, 83 SensorType, 84 }; ··· 528 TryFromButtplugClientMessage, 529 )] 530 #[cfg_attr(feature = "serialize-json", derive(Serialize, Deserialize))] 531 - pub(crate) enum ButtplugSpecV1ClientMessage { 532 // Handshake messages 533 RequestServerInfo(RequestServerInfo), 534 Ping(Ping), ··· 556 Debug, Clone, PartialEq, Eq, ButtplugMessage, ButtplugMessageValidator, ButtplugServerMessageType, 557 )] 558 #[cfg_attr(feature = "serialize-json", derive(Serialize, Deserialize))] 559 - pub(crate) enum ButtplugSpecV1ServerMessage { 560 // Status messages 561 Ok(Ok), 562 Error(ErrorV0), ··· 615 TryFromButtplugClientMessage, 616 )] 617 #[cfg_attr(feature = "serialize-json", derive(Serialize, Deserialize))] 618 - pub(crate) enum ButtplugSpecV0ClientMessage { 619 RequestLog(RequestLog), 620 Ping(Ping), 621 // Handshake messages ··· 641 Debug, Clone, PartialEq, Eq, ButtplugMessage, ButtplugMessageValidator, ButtplugServerMessageType, 642 )] 643 #[cfg_attr(feature = "serialize-json", derive(Serialize, Deserialize))] 644 - pub(crate) enum ButtplugSpecV0ServerMessage { 645 // Status messages 646 Ok(Ok), 647 Error(ErrorV0),
··· 27 mod log; 28 mod log_level; 29 mod lovense_cmd; 30 + mod client_device_message_attributes; 31 mod ok; 32 mod ping; 33 mod raw_read_cmd; ··· 72 pub use linear_cmd::{LinearCmd, VectorSubcommand}; 73 pub use log_level::LogLevel; 74 pub use lovense_cmd::LovenseCmd; 75 + pub use client_device_message_attributes::{ 76 ActuatorType, 77 + ClientDeviceMessageAttributes, 78 + ClientDeviceMessageAttributesBuilder, 79 + ClientDeviceMessageAttributesV1, 80 + ClientDeviceMessageAttributesV2, 81 + ClientGenericDeviceMessageAttributes, 82 + NullDeviceMessageAttributes, 83 + RawDeviceMessageAttributes, 84 SensorDeviceMessageAttributes, 85 SensorType, 86 }; ··· 530 TryFromButtplugClientMessage, 531 )] 532 #[cfg_attr(feature = "serialize-json", derive(Serialize, Deserialize))] 533 + pub enum ButtplugSpecV1ClientMessage { 534 // Handshake messages 535 RequestServerInfo(RequestServerInfo), 536 Ping(Ping), ··· 558 Debug, Clone, PartialEq, Eq, ButtplugMessage, ButtplugMessageValidator, ButtplugServerMessageType, 559 )] 560 #[cfg_attr(feature = "serialize-json", derive(Serialize, Deserialize))] 561 + pub enum ButtplugSpecV1ServerMessage { 562 // Status messages 563 Ok(Ok), 564 Error(ErrorV0), ··· 617 TryFromButtplugClientMessage, 618 )] 619 #[cfg_attr(feature = "serialize-json", derive(Serialize, Deserialize))] 620 + pub enum ButtplugSpecV0ClientMessage { 621 RequestLog(RequestLog), 622 Ping(Ping), 623 // Handshake messages ··· 643 Debug, Clone, PartialEq, Eq, ButtplugMessage, ButtplugMessageValidator, ButtplugServerMessageType, 644 )] 645 #[cfg_attr(feature = "serialize-json", derive(Serialize, Deserialize))] 646 + pub enum ButtplugSpecV0ServerMessage { 647 // Status messages 648 Ok(Ok), 649 Error(ErrorV0),
+11 -9
buttplug/src/server/device/configuration/mod.rs
··· 138 //! 139 140 pub mod specifier; 141 pub use specifier::*; 142 143 use super::protocol::{get_default_protocol_map, ProtocolIdentifierFactory, ProtocolSpecializer}; 144 use crate::{ 145 core::{ 146 errors::ButtplugDeviceError, 147 - messages::{ButtplugDeviceMessageType, DeviceMessageAttributes, Endpoint}, 148 }, 149 server::device::ServerDeviceIdentifier, 150 }; ··· 252 /// User configured name of the device this instance represents, assuming one exists. 253 display_name: Option<String>, 254 /// Message attributes for this device instance. 255 - pub(super) message_attributes: DeviceMessageAttributes, 256 } 257 258 impl ProtocolDeviceAttributes { ··· 261 identifier: ProtocolAttributesType, 262 name: Option<String>, 263 display_name: Option<String>, 264 - message_attributes: DeviceMessageAttributes, 265 parent: Option<Arc<ProtocolDeviceAttributes>>, 266 ) -> Self { 267 Self { ··· 349 } 350 351 /// Retreive a map of all message attributes for this instance. 352 - pub fn message_attributes(&self) -> DeviceMessageAttributes { 353 if let Some(parent) = &self.parent { 354 parent.message_attributes().merge(&self.message_attributes) 355 } else { ··· 711 712 #[cfg(test)] 713 mod test { 714 - use super::*; 715 - use crate::core::messages::{DeviceMessageAttributesBuilder, GenericDeviceMessageAttributes}; 716 use std::{ 717 collections::{HashMap, HashSet}, 718 ops::RangeInclusive, ··· 739 ProtocolAttributesType::Identifier("P".to_owned()), 740 Some("Lovense Edge".to_owned()), 741 None, 742 - DeviceMessageAttributesBuilder::default() 743 .scalar_cmd(&vec![ 744 - GenericDeviceMessageAttributes::new( 745 "Edge Vibrator 1", 746 &RangeInclusive::new(0, 20), 747 crate::core::messages::ActuatorType::Vibrate, 748 ), 749 - GenericDeviceMessageAttributes::new( 750 "Edge Vibrator 2", 751 &RangeInclusive::new(0, 20), 752 crate::core::messages::ActuatorType::Vibrate,
··· 138 //! 139 140 pub mod specifier; 141 + mod server_device_message_attributes; 142 pub use specifier::*; 143 + 144 + pub use server_device_message_attributes::{ServerDeviceMessageAttributes, ServerGenericDeviceMessageAttributes, ServerDeviceMessageAttributesBuilder}; 145 146 use super::protocol::{get_default_protocol_map, ProtocolIdentifierFactory, ProtocolSpecializer}; 147 use crate::{ 148 core::{ 149 errors::ButtplugDeviceError, 150 + messages::{ButtplugDeviceMessageType, Endpoint}, 151 }, 152 server::device::ServerDeviceIdentifier, 153 }; ··· 255 /// User configured name of the device this instance represents, assuming one exists. 256 display_name: Option<String>, 257 /// Message attributes for this device instance. 258 + pub(super) message_attributes: ServerDeviceMessageAttributes, 259 } 260 261 impl ProtocolDeviceAttributes { ··· 264 identifier: ProtocolAttributesType, 265 name: Option<String>, 266 display_name: Option<String>, 267 + message_attributes: ServerDeviceMessageAttributes, 268 parent: Option<Arc<ProtocolDeviceAttributes>>, 269 ) -> Self { 270 Self { ··· 352 } 353 354 /// Retreive a map of all message attributes for this instance. 355 + pub fn message_attributes(&self) -> ServerDeviceMessageAttributes { 356 if let Some(parent) = &self.parent { 357 parent.message_attributes().merge(&self.message_attributes) 358 } else { ··· 714 715 #[cfg(test)] 716 mod test { 717 + use super::{*, server_device_message_attributes::{ServerDeviceMessageAttributesBuilder, ServerGenericDeviceMessageAttributes}}; 718 use std::{ 719 collections::{HashMap, HashSet}, 720 ops::RangeInclusive, ··· 741 ProtocolAttributesType::Identifier("P".to_owned()), 742 Some("Lovense Edge".to_owned()), 743 None, 744 + ServerDeviceMessageAttributesBuilder::default() 745 .scalar_cmd(&vec![ 746 + ServerGenericDeviceMessageAttributes::new( 747 "Edge Vibrator 1", 748 &RangeInclusive::new(0, 20), 749 crate::core::messages::ActuatorType::Vibrate, 750 ), 751 + ServerGenericDeviceMessageAttributes::new( 752 "Edge Vibrator 2", 753 &RangeInclusive::new(0, 20), 754 crate::core::messages::ActuatorType::Vibrate,
+335
buttplug/src/server/device/configuration/server_device_message_attributes.rs
···
··· 1 + use std::ops::RangeInclusive; 2 + 3 + use serde::{Serialize, Deserialize}; 4 + use getset::{Getters, MutGetters, Setters}; 5 + 6 + use crate::core::{messages::{SensorDeviceMessageAttributes, NullDeviceMessageAttributes, RawDeviceMessageAttributes, ButtplugDeviceMessageType, SensorType, Endpoint, ActuatorType, ClientGenericDeviceMessageAttributes, ClientDeviceMessageAttributes, ClientDeviceMessageAttributesBuilder}, errors::ButtplugDeviceError}; 7 + 8 + // Unlike other message components, MessageAttributes is always turned on for 9 + // serialization, because it's used by device configuration files also. 10 + #[derive( 11 + Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, Getters, MutGetters, Setters, 12 + )] 13 + pub struct ServerDeviceMessageAttributes { 14 + // Generic commands 15 + #[getset(get = "pub", get_mut = "pub")] 16 + #[serde(rename = "ScalarCmd")] 17 + #[serde(skip_serializing_if = "Option::is_none")] 18 + scalar_cmd: Option<Vec<ServerGenericDeviceMessageAttributes>>, 19 + #[getset(get = "pub", get_mut = "pub")] 20 + #[serde(rename = "RotateCmd")] 21 + #[serde(skip_serializing_if = "Option::is_none")] 22 + rotate_cmd: Option<Vec<ServerGenericDeviceMessageAttributes>>, 23 + #[getset(get = "pub", get_mut = "pub")] 24 + #[serde(rename = "LinearCmd")] 25 + #[serde(skip_serializing_if = "Option::is_none")] 26 + linear_cmd: Option<Vec<ServerGenericDeviceMessageAttributes>>, 27 + 28 + // Sensor Messages 29 + #[getset(get = "pub")] 30 + #[serde(rename = "SensorReadCmd")] 31 + #[serde(skip_serializing_if = "Option::is_none")] 32 + sensor_read_cmd: Option<Vec<SensorDeviceMessageAttributes>>, 33 + #[getset(get = "pub")] 34 + #[serde(rename = "SensorSubscribeCmd")] 35 + #[serde(skip_serializing_if = "Option::is_none")] 36 + sensor_subscribe_cmd: Option<Vec<SensorDeviceMessageAttributes>>, 37 + 38 + // StopDeviceCmd always exists 39 + #[getset(get = "pub")] 40 + #[serde(rename = "StopDeviceCmd")] 41 + #[serde(skip_deserializing)] 42 + stop_device_cmd: NullDeviceMessageAttributes, 43 + 44 + // Raw commands are only added post-serialization 45 + #[getset(get = "pub")] 46 + #[serde(rename = "RawReadCmd")] 47 + #[serde(skip_deserializing)] 48 + #[serde(skip_serializing_if = "Option::is_none")] 49 + raw_read_cmd: Option<RawDeviceMessageAttributes>, 50 + // Raw commands are only added post-serialization 51 + #[getset(get = "pub")] 52 + #[serde(rename = "RawWriteCmd")] 53 + #[serde(skip_deserializing)] 54 + #[serde(skip_serializing_if = "Option::is_none")] 55 + raw_write_cmd: Option<RawDeviceMessageAttributes>, 56 + // Raw commands are only added post-serialization 57 + #[getset(get = "pub")] 58 + #[serde(rename = "RawSubscribeCmd")] 59 + #[serde(skip_deserializing)] 60 + #[serde(skip_serializing_if = "Option::is_none")] 61 + raw_subscribe_cmd: Option<RawDeviceMessageAttributes>, 62 + 63 + // Needed to load from config for fallback, but unused here. 64 + #[getset(get = "pub")] 65 + #[serde(rename = "FleshlightLaunchFW12Cmd")] 66 + #[serde(skip_serializing)] 67 + fleshlight_launch_fw12_cmd: Option<NullDeviceMessageAttributes>, 68 + #[getset(get = "pub")] 69 + #[serde(rename = "VorzeA10CycloneCmd")] 70 + #[serde(skip_serializing)] 71 + vorze_a10_cyclone_cmd: Option<NullDeviceMessageAttributes>, 72 + } 73 + 74 + impl ServerDeviceMessageAttributes { 75 + pub fn raw_unsubscribe_cmd(&self) -> &Option<RawDeviceMessageAttributes> { 76 + self.raw_subscribe_cmd() 77 + } 78 + 79 + pub fn message_allowed(&self, message_type: &ButtplugDeviceMessageType) -> bool { 80 + match message_type { 81 + ButtplugDeviceMessageType::ScalarCmd => self.scalar_cmd.is_some(), 82 + // VibrateCmd and SingleMotorVibrateCmd will derive from Scalars, so errors will be thrown in 83 + // the scalar parser if the actuator isn't correct. 84 + ButtplugDeviceMessageType::VibrateCmd => self.scalar_cmd.is_some(), 85 + ButtplugDeviceMessageType::SingleMotorVibrateCmd => self.scalar_cmd.is_some(), 86 + ButtplugDeviceMessageType::SensorReadCmd => self.sensor_read_cmd.is_some(), 87 + ButtplugDeviceMessageType::SensorSubscribeCmd => self.sensor_subscribe_cmd.is_some(), 88 + ButtplugDeviceMessageType::SensorUnsubscribeCmd => self.sensor_subscribe_cmd.is_some(), 89 + ButtplugDeviceMessageType::LinearCmd => self.linear_cmd.is_some(), 90 + ButtplugDeviceMessageType::RotateCmd => self.rotate_cmd.is_some(), 91 + ButtplugDeviceMessageType::BatteryLevelCmd => { 92 + if let Some(sensor_info) = &self.sensor_read_cmd { 93 + sensor_info 94 + .iter() 95 + .any(|x| *x.sensor_type() == SensorType::Battery) 96 + } else { 97 + false 98 + } 99 + } 100 + ButtplugDeviceMessageType::FleshlightLaunchFW12Cmd => { 101 + self.fleshlight_launch_fw12_cmd.is_some() 102 + } 103 + ButtplugDeviceMessageType::RSSILevelCmd => { 104 + if let Some(sensor_info) = &self.sensor_read_cmd { 105 + sensor_info 106 + .iter() 107 + .any(|x| *x.sensor_type() == SensorType::RSSI) 108 + } else { 109 + false 110 + } 111 + } 112 + ButtplugDeviceMessageType::RawReadCmd => self.raw_read_cmd.is_some(), 113 + ButtplugDeviceMessageType::RawSubscribeCmd => self.raw_subscribe_cmd.is_some(), 114 + ButtplugDeviceMessageType::RawUnsubscribeCmd => self.raw_subscribe_cmd.is_some(), 115 + ButtplugDeviceMessageType::RawWriteCmd => self.raw_write_cmd.is_some(), 116 + ButtplugDeviceMessageType::VorzeA10CycloneCmd => self.vorze_a10_cyclone_cmd.is_some(), 117 + ButtplugDeviceMessageType::StopDeviceCmd => true, 118 + ButtplugDeviceMessageType::KiirooCmd => false, 119 + ButtplugDeviceMessageType::LovenseCmd => false, 120 + } 121 + } 122 + 123 + pub fn merge(&self, child: &ServerDeviceMessageAttributes) -> ServerDeviceMessageAttributes { 124 + Self { 125 + rotate_cmd: child 126 + .rotate_cmd() 127 + .clone() 128 + .or_else(|| self.rotate_cmd().clone()), 129 + linear_cmd: child 130 + .linear_cmd() 131 + .clone() 132 + .or_else(|| self.linear_cmd().clone()), 133 + scalar_cmd: child 134 + .scalar_cmd() 135 + .clone() 136 + .or_else(|| self.scalar_cmd().clone()), 137 + sensor_read_cmd: child 138 + .sensor_read_cmd() 139 + .clone() 140 + .or_else(|| self.sensor_read_cmd().clone()), 141 + sensor_subscribe_cmd: child 142 + .sensor_subscribe_cmd() 143 + .clone() 144 + .or_else(|| self.sensor_subscribe_cmd().clone()), 145 + stop_device_cmd: NullDeviceMessageAttributes::default(), 146 + raw_read_cmd: child 147 + .raw_read_cmd() 148 + .clone() 149 + .or_else(|| self.raw_read_cmd().clone()), 150 + raw_write_cmd: child 151 + .raw_write_cmd() 152 + .clone() 153 + .or_else(|| self.raw_write_cmd().clone()), 154 + raw_subscribe_cmd: child 155 + .raw_subscribe_cmd() 156 + .clone() 157 + .or_else(|| self.raw_subscribe_cmd().clone()), 158 + fleshlight_launch_fw12_cmd: child 159 + .fleshlight_launch_fw12_cmd() 160 + .clone() 161 + .or_else(|| self.fleshlight_launch_fw12_cmd().clone()), 162 + vorze_a10_cyclone_cmd: child 163 + .vorze_a10_cyclone_cmd() 164 + .clone() 165 + .or_else(|| self.vorze_a10_cyclone_cmd().clone()), 166 + } 167 + } 168 + 169 + pub fn add_raw_messages(&mut self, endpoints: &[Endpoint]) { 170 + let raw_attrs = RawDeviceMessageAttributes::new(&endpoints.to_vec()); 171 + self.raw_read_cmd = Some(raw_attrs.clone()); 172 + self.raw_write_cmd = Some(raw_attrs.clone()); 173 + self.raw_subscribe_cmd = Some(raw_attrs.clone()); 174 + } 175 + } 176 + 177 + impl Into<ClientDeviceMessageAttributes> for ServerDeviceMessageAttributes { 178 + fn into(self) -> ClientDeviceMessageAttributes { 179 + let mut builder = ClientDeviceMessageAttributesBuilder::default(); 180 + if let Some(scalar_cmd) = self.scalar_cmd { 181 + builder.scalar_cmd(&scalar_cmd.iter().cloned().map(|x| x.into()).collect()); 182 + } 183 + if let Some(rotate_cmd) = self.rotate_cmd { 184 + builder.rotate_cmd(&rotate_cmd.iter().cloned().map(|x| x.into()).collect()); 185 + } 186 + if let Some(linear_cmd) = self.linear_cmd { 187 + builder.linear_cmd(&linear_cmd.iter().cloned().map(|x| x.into()).collect()); 188 + } 189 + if let Some(sensor_read_cmd) = self.sensor_read_cmd { 190 + builder.sensor_read_cmd(&sensor_read_cmd); 191 + } 192 + if let Some(sensor_subscribe_cmd) = self.sensor_subscribe_cmd { 193 + builder.sensor_subscribe_cmd(&sensor_subscribe_cmd); 194 + } 195 + if let Some(raw_read_cmd) = self.raw_read_cmd { 196 + builder.raw_read_cmd(raw_read_cmd.endpoints()); 197 + } 198 + if let Some(raw_write_cmd) = self.raw_write_cmd { 199 + builder.raw_write_cmd(raw_write_cmd.endpoints()); 200 + } 201 + if let Some(raw_subscribe_cmd) = self.raw_subscribe_cmd { 202 + builder.raw_subscribe_cmd(raw_subscribe_cmd.endpoints()); 203 + } 204 + builder.finish() 205 + } 206 + } 207 + 208 + #[derive(Default)] 209 + pub struct ServerDeviceMessageAttributesBuilder { 210 + attrs: ServerDeviceMessageAttributes, 211 + } 212 + 213 + impl ServerDeviceMessageAttributesBuilder { 214 + pub fn scalar_cmd(&mut self, attrs: &Vec<ServerGenericDeviceMessageAttributes>) -> &Self { 215 + self.attrs.scalar_cmd = Some(attrs.clone()); 216 + self 217 + } 218 + 219 + pub fn rotate_cmd(&mut self, attrs: &Vec<ServerGenericDeviceMessageAttributes>) -> &Self { 220 + self.attrs.rotate_cmd = Some(attrs.clone()); 221 + self 222 + } 223 + 224 + pub fn linear_cmd(&mut self, attrs: &Vec<ServerGenericDeviceMessageAttributes>) -> &Self { 225 + self.attrs.linear_cmd = Some(attrs.clone()); 226 + self 227 + } 228 + 229 + pub fn sensor_read_cmd(&mut self, attrs: &Vec<SensorDeviceMessageAttributes>) -> &Self { 230 + self.attrs.sensor_read_cmd = Some(attrs.clone()); 231 + self 232 + } 233 + 234 + pub fn sensor_subscribe_cmd(&mut self, attrs: &Vec<SensorDeviceMessageAttributes>) -> &Self { 235 + self.attrs.sensor_subscribe_cmd = Some(attrs.clone()); 236 + self 237 + } 238 + 239 + pub fn raw_read_cmd(&mut self, endpoints: &Vec<Endpoint>) -> &Self { 240 + self.attrs.raw_read_cmd = Some(RawDeviceMessageAttributes::new(endpoints)); 241 + self 242 + } 243 + 244 + pub fn raw_write_cmd(&mut self, endpoints: &Vec<Endpoint>) -> &Self { 245 + self.attrs.raw_write_cmd = Some(RawDeviceMessageAttributes::new(endpoints)); 246 + self 247 + } 248 + 249 + pub fn raw_subscribe_cmd(&mut self, endpoints: &Vec<Endpoint>) -> &Self { 250 + self.attrs.raw_subscribe_cmd = Some(RawDeviceMessageAttributes::new(endpoints)); 251 + self 252 + } 253 + 254 + pub fn finish(&self) -> ServerDeviceMessageAttributes { 255 + self.attrs.clone() 256 + } 257 + } 258 + 259 + fn unspecified_feature() -> String { 260 + "No description available for feature".to_string() 261 + } 262 + 263 + #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Getters, Setters)] 264 + pub struct ServerGenericDeviceMessageAttributes { 265 + #[getset(get = "pub")] 266 + #[serde(rename = "FeatureDescriptor")] 267 + #[serde(default = "unspecified_feature")] 268 + feature_descriptor: String, 269 + #[getset(get = "pub")] 270 + #[serde(rename = "ActuatorType")] 271 + actuator_type: ActuatorType, 272 + #[serde(rename = "StepRange")] 273 + #[serde(skip_serializing)] 274 + #[getset(get = "pub", set = "pub")] 275 + step_range: RangeInclusive<u32>, 276 + } 277 + 278 + impl Into<ClientGenericDeviceMessageAttributes> for ServerGenericDeviceMessageAttributes { 279 + fn into(self) -> ClientGenericDeviceMessageAttributes { 280 + ClientGenericDeviceMessageAttributes::new( 281 + &self.feature_descriptor, 282 + self.step_count(), 283 + self.actuator_type, 284 + ) 285 + } 286 + } 287 + 288 + impl ServerGenericDeviceMessageAttributes { 289 + pub fn new( 290 + feature_descriptor: &str, 291 + step_range: &RangeInclusive<u32>, 292 + actuator_type: ActuatorType, 293 + ) -> Self { 294 + Self { 295 + feature_descriptor: feature_descriptor.to_owned(), 296 + actuator_type, 297 + step_range: step_range.clone(), 298 + } 299 + } 300 + 301 + pub fn step_count(&self) -> u32 { 302 + self.step_range.end() - self.step_range.start() 303 + } 304 + 305 + pub fn is_valid( 306 + &self, 307 + message_type: &ButtplugDeviceMessageType, 308 + ) -> Result<(), ButtplugDeviceError> { 309 + if self.step_range.is_empty() { 310 + Err(ButtplugDeviceError::DeviceConfigurationError(format!( 311 + "Step range out of order for {}, must be start <= x <= end.", 312 + message_type 313 + ))) 314 + } else { 315 + Ok(()) 316 + } 317 + } 318 + } 319 + 320 + #[cfg(test)] 321 + mod test { 322 + use super::*; 323 + 324 + #[test] 325 + pub fn test_step_count_calculation() { 326 + let mut vibrate_attributes = ServerGenericDeviceMessageAttributes::new( 327 + "test", 328 + &RangeInclusive::new(0, 10), 329 + ActuatorType::Vibrate, 330 + ); 331 + assert_eq!(vibrate_attributes.step_count(), 10); 332 + vibrate_attributes.set_step_range(RangeInclusive::new(3u32, 7)); 333 + assert_eq!(vibrate_attributes.step_count(), 4); 334 + } 335 + }
+11 -13
buttplug/src/server/device/protocol/generic_command_manager.rs
··· 11 messages::{ 12 ActuatorType, 13 ButtplugDeviceCommandMessageUnion, 14 - GenericDeviceMessageAttributes, 15 LinearCmd, 16 RotateCmd, 17 RotationSubcommand, ··· 19 ScalarSubcommand, 20 }, 21 }, 22 - server::device::configuration::ProtocolDeviceAttributes, 23 }; 24 use getset::Getters; 25 use std::{ ··· 36 } 37 38 impl ScalarGenericCommand { 39 - pub fn new(attributes: &GenericDeviceMessageAttributes) -> Self { 40 Self { 41 actuator: attributes.actuator_type().clone(), 42 step_range: attributes.step_range().clone(), ··· 325 use crate::{ 326 core::messages::{ 327 ActuatorType, 328 - DeviceMessageAttributesBuilder, 329 - GenericDeviceMessageAttributes, 330 RotateCmd, 331 RotationSubcommand, 332 ScalarCmd, 333 ScalarSubcommand, 334 }, 335 - server::device::configuration::ProtocolAttributesType, 336 }; 337 use std::ops::RangeInclusive; 338 339 #[test] 340 pub fn test_command_generator_vibration() { 341 - let scalar_attrs = GenericDeviceMessageAttributes::new( 342 "Test", 343 &RangeInclusive::new(0, 20), 344 ActuatorType::Vibrate, 345 ); 346 - let scalar_attributes = DeviceMessageAttributesBuilder::default() 347 .scalar_cmd(&vec![scalar_attrs.clone(), scalar_attrs.clone()]) 348 .finish(); 349 let device_attributes = ProtocolDeviceAttributes::new( ··· 406 407 #[test] 408 pub fn test_command_generator_vibration_step_range() { 409 - let mut vibrate_attrs_1 = GenericDeviceMessageAttributes::new( 410 "Test", 411 &RangeInclusive::new(0, 20), 412 ActuatorType::Vibrate, 413 ); 414 vibrate_attrs_1.set_step_range(RangeInclusive::new(10, 15)); 415 - let mut vibrate_attrs_2 = GenericDeviceMessageAttributes::new( 416 "Test", 417 &RangeInclusive::new(0, 20), 418 ActuatorType::Vibrate, 419 ); 420 vibrate_attrs_2.set_step_range(RangeInclusive::new(10, 20)); 421 422 - let vibrate_attributes = DeviceMessageAttributesBuilder::default() 423 .scalar_cmd(&vec![vibrate_attrs_1, vibrate_attrs_2]) 424 .finish(); 425 let device_attributes = ProtocolDeviceAttributes::new( ··· 482 483 #[test] 484 pub fn test_command_generator_rotation() { 485 - let rotate_attrs = GenericDeviceMessageAttributes::new( 486 "Test", 487 &RangeInclusive::new(0, 20), 488 ActuatorType::Rotate, 489 ); 490 491 - let rotate_attributes = DeviceMessageAttributesBuilder::default() 492 .rotate_cmd(&vec![rotate_attrs.clone(), rotate_attrs]) 493 .finish(); 494 let device_attributes = ProtocolDeviceAttributes::new(
··· 11 messages::{ 12 ActuatorType, 13 ButtplugDeviceCommandMessageUnion, 14 + ClientGenericDeviceMessageAttributes, 15 LinearCmd, 16 RotateCmd, 17 RotationSubcommand, ··· 19 ScalarSubcommand, 20 }, 21 }, 22 + server::device::configuration::{ProtocolDeviceAttributes, ServerGenericDeviceMessageAttributes}, 23 }; 24 use getset::Getters; 25 use std::{ ··· 36 } 37 38 impl ScalarGenericCommand { 39 + pub fn new(attributes: &ServerGenericDeviceMessageAttributes) -> Self { 40 Self { 41 actuator: attributes.actuator_type().clone(), 42 step_range: attributes.step_range().clone(), ··· 325 use crate::{ 326 core::messages::{ 327 ActuatorType, 328 RotateCmd, 329 RotationSubcommand, 330 ScalarCmd, 331 ScalarSubcommand, 332 }, 333 + server::device::configuration::{ProtocolAttributesType, ServerGenericDeviceMessageAttributes, ServerDeviceMessageAttributesBuilder}, 334 }; 335 use std::ops::RangeInclusive; 336 337 #[test] 338 pub fn test_command_generator_vibration() { 339 + let scalar_attrs = ServerGenericDeviceMessageAttributes::new( 340 "Test", 341 &RangeInclusive::new(0, 20), 342 ActuatorType::Vibrate, 343 ); 344 + let scalar_attributes = ServerDeviceMessageAttributesBuilder::default() 345 .scalar_cmd(&vec![scalar_attrs.clone(), scalar_attrs.clone()]) 346 .finish(); 347 let device_attributes = ProtocolDeviceAttributes::new( ··· 404 405 #[test] 406 pub fn test_command_generator_vibration_step_range() { 407 + let mut vibrate_attrs_1 = ServerGenericDeviceMessageAttributes::new( 408 "Test", 409 &RangeInclusive::new(0, 20), 410 ActuatorType::Vibrate, 411 ); 412 vibrate_attrs_1.set_step_range(RangeInclusive::new(10, 15)); 413 + let mut vibrate_attrs_2 = ServerGenericDeviceMessageAttributes::new( 414 "Test", 415 &RangeInclusive::new(0, 20), 416 ActuatorType::Vibrate, 417 ); 418 vibrate_attrs_2.set_step_range(RangeInclusive::new(10, 20)); 419 420 + let vibrate_attributes = ServerDeviceMessageAttributesBuilder::default() 421 .scalar_cmd(&vec![vibrate_attrs_1, vibrate_attrs_2]) 422 .finish(); 423 let device_attributes = ProtocolDeviceAttributes::new( ··· 480 481 #[test] 482 pub fn test_command_generator_rotation() { 483 + let rotate_attrs = ServerGenericDeviceMessageAttributes::new( 484 "Test", 485 &RangeInclusive::new(0, 20), 486 ActuatorType::Rotate, 487 ); 488 489 + let rotate_attributes = ServerDeviceMessageAttributesBuilder::default() 490 .rotate_cmd(&vec![rotate_attrs.clone(), rotate_attrs]) 491 .finish(); 492 let device_attributes = ProtocolDeviceAttributes::new(
+3 -3
buttplug/src/server/device/server_device.rs
··· 21 ButtplugDeviceMessageType, 22 ButtplugMessage, 23 ButtplugServerDeviceMessage, 24 - DeviceMessageAttributes, 25 Endpoint, 26 RawReading, 27 RawSubscribeCmd, ··· 50 use tokio_stream::StreamExt; 51 52 use super::{ 53 - configuration::ProtocolDeviceAttributes, 54 protocol::generic_command_manager::GenericCommandManager, 55 }; 56 ··· 263 } 264 265 /// Retreive the message attributes for the device. 266 - pub fn message_attributes(&self) -> DeviceMessageAttributes { 267 self.attributes.message_attributes() 268 } 269
··· 21 ButtplugDeviceMessageType, 22 ButtplugMessage, 23 ButtplugServerDeviceMessage, 24 + ClientDeviceMessageAttributes, 25 Endpoint, 26 RawReading, 27 RawSubscribeCmd, ··· 50 use tokio_stream::StreamExt; 51 52 use super::{ 53 + configuration::{ProtocolDeviceAttributes, ServerDeviceMessageAttributes}, 54 protocol::generic_command_manager::GenericCommandManager, 55 }; 56 ··· 263 } 264 265 /// Retreive the message attributes for the device. 266 + pub fn message_attributes(&self) -> ServerDeviceMessageAttributes { 267 self.attributes.message_attributes() 268 } 269
+1 -1
buttplug/src/server/device/server_device_manager.rs
··· 286 .iter() 287 .map(|device| { 288 let dev = device.value(); 289 - DeviceMessageInfo::new(*device.key(), &dev.name(), dev.message_attributes()) 290 }) 291 .collect(); 292 let mut device_list = DeviceList::new(devices);
··· 286 .iter() 287 .map(|device| { 288 let dev = device.value(); 289 + DeviceMessageInfo::new(*device.key(), &dev.name(), dev.message_attributes().clone().into()) 290 }) 291 .collect(); 292 let mut device_list = DeviceList::new(devices);
+1 -1
buttplug/src/server/device/server_device_manager_event_loop.rs
··· 265 266 info!("Assigning index {} to {}", device_index, device.name()); 267 let device_added_message = 268 - DeviceAdded::new(device_index, &device.name(), &device.message_attributes()); 269 self.device_map.insert(device_index, device); 270 // After that, we can send out to the server's event listeners to let 271 // them know a device has been added.
··· 265 266 info!("Assigning index {} to {}", device_index, device.name()); 267 let device_added_message = 268 + DeviceAdded::new(device_index, &device.name(), &device.message_attributes().clone().into()); 269 self.device_map.insert(device_index, device); 270 // After that, we can send out to the server's event listeners to let 271 // them know a device has been added.
+4 -4
buttplug/src/util/device_configuration.rs
··· 7 8 use super::json::JSONValidator; 9 use crate::{ 10 - core::{errors::ButtplugDeviceError, messages::DeviceMessageAttributes}, 11 server::device::{ 12 configuration::{ 13 BluetoothLESpecifier, ··· 22 SerialSpecifier, 23 USBSpecifier, 24 WebsocketSpecifier, 25 - XInputSpecifier, 26 }, 27 ServerDeviceIdentifier, 28 }, ··· 88 deny: Option<bool>, 89 #[serde(skip_serializing_if = "Option::is_none")] 90 #[serde(default)] 91 - messages: Option<DeviceMessageAttributes>, 92 #[serde(skip_serializing_if = "Option::is_none")] 93 #[serde(default)] 94 index: Option<u32>, ··· 102 #[serde(skip_serializing_if = "Option::is_none")] 103 name: Option<String>, 104 #[serde(skip_serializing_if = "Option::is_none")] 105 - messages: Option<DeviceMessageAttributes>, 106 } 107 108 #[derive(Deserialize, Serialize, Debug, Clone, Default, Getters, Setters, MutGetters)]
··· 7 8 use super::json::JSONValidator; 9 use crate::{ 10 + core::errors::ButtplugDeviceError, 11 server::device::{ 12 configuration::{ 13 BluetoothLESpecifier, ··· 22 SerialSpecifier, 23 USBSpecifier, 24 WebsocketSpecifier, 25 + XInputSpecifier, ServerDeviceMessageAttributes, 26 }, 27 ServerDeviceIdentifier, 28 }, ··· 88 deny: Option<bool>, 89 #[serde(skip_serializing_if = "Option::is_none")] 90 #[serde(default)] 91 + messages: Option<ServerDeviceMessageAttributes>, 92 #[serde(skip_serializing_if = "Option::is_none")] 93 #[serde(default)] 94 index: Option<u32>, ··· 102 #[serde(skip_serializing_if = "Option::is_none")] 103 name: Option<String>, 104 #[serde(skip_serializing_if = "Option::is_none")] 105 + messages: Option<ServerDeviceMessageAttributes>, 106 } 107 108 #[derive(Deserialize, Serialize, Debug, Clone, Default, Getters, Setters, MutGetters)]