···11+22+use buttplug_core::errors::ButtplugDeviceError;
33+use dashmap::DashMap;
44+use getset::Getters;
55+use std::{
66+ collections::HashMap,
77+ fmt::{self, Debug},
88+};
99+1010+use crate::{BaseDeviceIdentifier, ProtocolCommunicationSpecifier, ServerDeviceDefinition, UserDeviceIdentifier};
1111+1212+#[derive(Default, Clone)]
1313+pub struct DeviceConfigurationManagerBuilder {
1414+ communication_specifiers: HashMap<String, Vec<ProtocolCommunicationSpecifier>>,
1515+ user_communication_specifiers: DashMap<String, Vec<ProtocolCommunicationSpecifier>>,
1616+ base_device_definitions: HashMap<BaseDeviceIdentifier, ServerDeviceDefinition>,
1717+ user_device_definitions: DashMap<UserDeviceIdentifier, ServerDeviceDefinition>,
1818+}
1919+2020+impl DeviceConfigurationManagerBuilder {
2121+ pub fn communication_specifier(
2222+ &mut self,
2323+ protocol_name: &str,
2424+ specifier: &[ProtocolCommunicationSpecifier],
2525+ ) -> &mut Self {
2626+ self
2727+ .communication_specifiers
2828+ .entry(protocol_name.to_owned())
2929+ .or_default()
3030+ .extend(specifier.iter().cloned());
3131+ self
3232+ }
3333+3434+ pub fn protocol_features(
3535+ &mut self,
3636+ identifier: &BaseDeviceIdentifier,
3737+ features: &ServerDeviceDefinition,
3838+ ) -> &mut Self {
3939+ self
4040+ .base_device_definitions
4141+ .insert(identifier.clone(), features.clone());
4242+ self
4343+ }
4444+4545+ pub fn user_communication_specifier(
4646+ &mut self,
4747+ protocol_name: &str,
4848+ specifier: &[ProtocolCommunicationSpecifier],
4949+ ) -> &mut Self {
5050+ self
5151+ .user_communication_specifiers
5252+ .entry(protocol_name.to_owned())
5353+ .or_default()
5454+ .extend(specifier.iter().cloned());
5555+ self
5656+ }
5757+5858+ pub fn user_protocol_features(
5959+ &mut self,
6060+ identifier: &UserDeviceIdentifier,
6161+ features: &ServerDeviceDefinition,
6262+ ) -> &mut Self {
6363+ if let Some((_, base_definition)) = self
6464+ .base_device_definitions
6565+ .iter()
6666+ .find(|(_, x)| x.id() == features.base_id())
6767+ {
6868+ self.user_device_definitions.insert(
6969+ identifier.clone(),
7070+ ServerDeviceDefinition::new(base_definition, features),
7171+ );
7272+ } else {
7373+ error!(
7474+ "Cannot find protocol with base id {} for user id {}",
7575+ features.base_id(),
7676+ features.id()
7777+ )
7878+ }
7979+ self
8080+ }
8181+8282+ pub fn finish(&mut self) -> Result<DeviceConfigurationManager, ButtplugDeviceError> {
8383+ // Build and validate the protocol attributes tree.
8484+ let mut attribute_tree_map = HashMap::new();
8585+8686+ // Add all the defaults first, they won't have parent attributes.
8787+ for (ident, attr) in &self.base_device_definitions {
8888+ /*
8989+ for feature in attr.features() {
9090+ if let Err(e) = feature.is_valid() {
9191+ error!("Feature {attr:?} for ident {ident:?} is not valid, skipping addition: {e:?}");
9292+ continue;
9393+ }
9494+ }
9595+ */
9696+ attribute_tree_map.insert(ident.clone(), attr.clone());
9797+ }
9898+9999+ let user_attribute_tree_map = DashMap::new();
100100+ // Finally, add in user configurations, which will have an address.
101101+ for kv in &self.user_device_definitions {
102102+ let (ident, attr) = (kv.key(), kv.value());
103103+ for feature in attr.features() {
104104+ if let Err(e) = feature.is_valid() {
105105+ error!("Feature {attr:?} for ident {ident:?} is not valid, skipping addition: {e:?}");
106106+ continue;
107107+ }
108108+ }
109109+ user_attribute_tree_map.insert(kv.key().clone(), kv.value().clone());
110110+ }
111111+112112+ Ok(DeviceConfigurationManager {
113113+ base_communication_specifiers: self.communication_specifiers.clone(),
114114+ user_communication_specifiers: self.user_communication_specifiers.clone(),
115115+ base_device_definitions: attribute_tree_map,
116116+ user_device_definitions: user_attribute_tree_map,
117117+ //protocol_map,
118118+ })
119119+ }
120120+}
121121+122122+/// Correlates information about protocols and which devices they support.
123123+///
124124+/// The [DeviceConfigurationManager] handles stores information about which device protocols the
125125+/// library supports, as well as which devices can use those protocols. When a
126126+/// [DeviceCommunicationManager](crate::server::device::communication_manager) finds a device during scanning,
127127+/// device information is given to the [DeviceConfigurationManager] to decide whether Buttplug
128128+/// should try to connect to and communicate with the device.
129129+///
130130+/// Assuming the device is supported by the library, the [DeviceConfigurationManager] also stores
131131+/// information about what commands can be sent to the device (Vibrate, Rotate, etc...), and the
132132+/// parameters for those commands (number of power levels, stroke distances, etc...).
133133+#[derive(Getters)]
134134+#[getset(get = "pub")]
135135+pub struct DeviceConfigurationManager {
136136+ /// Communication specifiers from the base device config, mapped from protocol name to vector of
137137+ /// specifiers. Should not change/update during a session.
138138+ base_communication_specifiers: HashMap<String, Vec<ProtocolCommunicationSpecifier>>,
139139+ /// Device definitions from the base device config. Should not change/update during a session.
140140+ base_device_definitions: HashMap<BaseDeviceIdentifier, ServerDeviceDefinition>,
141141+ /// Communication specifiers provided by the user, mapped from protocol name to vector of
142142+ /// specifiers. Loaded at session start, may change over life of session.
143143+ user_communication_specifiers: DashMap<String, Vec<ProtocolCommunicationSpecifier>>,
144144+ /// Device definitions from the user device config. Loaded at session start, may change over life
145145+ /// of session.
146146+ user_device_definitions: DashMap<UserDeviceIdentifier, ServerDeviceDefinition>,
147147+}
148148+149149+impl Debug for DeviceConfigurationManager {
150150+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
151151+ f.debug_struct("DeviceConfigurationManager").finish()
152152+ }
153153+}
154154+155155+impl Default for DeviceConfigurationManager {
156156+ fn default() -> Self {
157157+ // Unwrap allowed here because we assume our built in device config will
158158+ // always work. System won't pass tests or possibly even build otherwise.
159159+ DeviceConfigurationManagerBuilder::default()
160160+ .finish()
161161+ .expect("Default creation of a DCM should always work.")
162162+ }
163163+}
164164+165165+impl DeviceConfigurationManager {
166166+ pub fn add_user_communication_specifier(
167167+ &self,
168168+ protocol: &str,
169169+ specifier: &ProtocolCommunicationSpecifier,
170170+ ) -> Result<(), ButtplugDeviceError> {
171171+ //self.protocol_map.contains_key(protocol);
172172+ self
173173+ .user_communication_specifiers
174174+ .entry(protocol.to_owned())
175175+ .or_default()
176176+ .push(specifier.clone());
177177+ Ok(())
178178+ }
179179+180180+ pub fn remove_user_communication_specifier(
181181+ &self,
182182+ protocol: &str,
183183+ specifier: &ProtocolCommunicationSpecifier,
184184+ ) {
185185+ if let Some(mut specifiers) = self.user_communication_specifiers.get_mut(protocol) {
186186+ let specifier_vec = specifiers.value_mut();
187187+ *specifier_vec = specifier_vec
188188+ .iter()
189189+ .filter(|s| *specifier != **s)
190190+ .cloned()
191191+ .collect();
192192+ }
193193+ }
194194+195195+ pub fn add_user_device_definition(
196196+ &self,
197197+ identifier: &UserDeviceIdentifier,
198198+ definition: &ServerDeviceDefinition,
199199+ ) -> Result<(), ButtplugDeviceError> {
200200+ //self.protocol_map.contains_key(identifier.protocol());
201201+ // Check validity of device
202202+ let mut index = definition.user_config().index();
203203+ let indexes: Vec<u32> = self.user_device_definitions().iter().map(|x| x.value().user_config().index()).collect();
204204+ // If we just added 1 to the maximum value of the current indexes, someone decides to set an
205205+ // index to u32::MAX-1, then we'd have a problem. This is kind of a shit solution but it'll work
206206+ // quickly for anyone that's not actively fucking with us by manually playing with user config files.
207207+ while indexes.contains(&index) {
208208+ index = index.wrapping_add(1);
209209+ }
210210+ let mut def = definition.clone();
211211+ *def.user_device_mut().user_config_mut().index_mut() = index;
212212+ self
213213+ .user_device_definitions
214214+ .entry(identifier.clone())
215215+ .insert(def);
216216+ Ok(())
217217+ }
218218+219219+ pub fn remove_user_device_definition(&self, identifier: &UserDeviceIdentifier) {
220220+ self.user_device_definitions.remove(identifier);
221221+ }
222222+223223+ pub fn address_allowed(&self, address: &str) -> bool {
224224+ // Make sure the device isn't on the deny list
225225+ if self
226226+ .user_device_definitions
227227+ .iter()
228228+ .any(|kv| kv.key().address() == address && kv.value().user_config().deny())
229229+ {
230230+ // If device is outright denied, deny
231231+ info!(
232232+ "Device {} denied by configuration, not connecting.",
233233+ address
234234+ );
235235+ false
236236+ } else if self
237237+ .user_device_definitions
238238+ .iter()
239239+ .any(|kv| kv.value().user_config().allow())
240240+ && !self
241241+ .user_device_definitions
242242+ .iter()
243243+ .any(|kv| kv.key().address() == address && kv.value().user_config().allow())
244244+ {
245245+ // If device is not on allow list and allow list isn't empty, deny
246246+ info!(
247247+ "Device {} not on allow list and allow list not empty, not connecting.",
248248+ address
249249+ );
250250+ false
251251+ } else {
252252+ true
253253+ }
254254+ }
255255+256256+ fn device_index(&self, identifier: &UserDeviceIdentifier) -> u32 {
257257+ // See if we have a reserved or reusable device index here.
258258+ if let Some(config) = self.user_device_definitions.get(identifier) {
259259+ let index = config.user_config().index();
260260+ debug!("Found index {index} for device {identifier:?}");
261261+ return index;
262262+ }
263263+264264+ let current_indexes: Vec<u32> = self
265265+ .user_device_definitions
266266+ .iter()
267267+ .map(|x| x.user_config().index())
268268+ .collect();
269269+270270+ // Someone is gonna make a max device index in their config file just to fuck with me, therefore
271271+ // we don't do "max + 1", we fill in holes (lol) in sequences. To whomever has 4 billion sex toys:
272272+ // sorry your index finding for new devices is slow and takes 16GB of allocation every time we
273273+ // want to search the index space.
274274+275275+ let mut index = 0;
276276+ while current_indexes.contains(&index) {
277277+ index += 1;
278278+ }
279279+ debug!("Generating and assigning index {index:?} for device {identifier:?}");
280280+ index
281281+ }
282282+283283+ /// Provides read-only access to the internal protocol/identifier map. Mainly
284284+ /// used for WebBluetooth filter construction, but could also be handy for
285285+ /// listing capabilities in UI, etc.
286286+ pub fn protocol_device_configurations(
287287+ &self,
288288+ ) -> HashMap<String, Vec<ProtocolCommunicationSpecifier>> {
289289+ self.base_communication_specifiers.clone()
290290+ }
291291+292292+ pub fn device_definition(&self, identifier: &UserDeviceIdentifier) -> Option<DeviceDefinition> {
293293+ let features = if let Some(attrs) = self.user_device_definitions.get(identifier) {
294294+ debug!("User device config found for {:?}", identifier);
295295+ attrs.clone()
296296+ } else if let Some(attrs) = self.base_device_definitions.get(&BaseDeviceIdentifier::new(
297297+ identifier.protocol(),
298298+ identifier.identifier(),
299299+ )) {
300300+ debug!(
301301+ "Protocol + Identifier device config found for {:?}",
302302+ identifier
303303+ );
304304+ DeviceDefinition::new_from_base_definition(attrs, self.device_index(identifier))
305305+ } else if let Some(attrs) = self
306306+ .base_device_definitions
307307+ .get(&BaseDeviceIdentifier::new(identifier.protocol(), &None))
308308+ {
309309+ debug!("Protocol device config found for {:?}", identifier);
310310+ DeviceDefinition::new_from_base_definition(attrs, self.device_index(identifier))
311311+ } else {
312312+ return None;
313313+ };
314314+315315+ // If this is a new device, it needs to be added to the user device definition map.
316316+ //
317317+ // Device definitions are looked up before we fully initialize a device, mostly for algorithm
318318+ // preparation. There is a very small chance we may save the device config then error out when
319319+ // we connect to the device, but we'll assume we may connect successfully later.
320320+ if self.user_device_definitions.get(identifier).is_none() {
321321+ self
322322+ .user_device_definitions
323323+ .insert(identifier.clone(), features.clone());
324324+ }
325325+326326+ Some(features)
327327+ }
328328+}
···13131414use core::hash::Hash;
15151616-// We need this array to be exposed in our WASM FFI, but the only way to do that
1717-// is to expose it at the declaration level. Therefore, we use the WASM feature
1818-// to assume we're building for WASM and attach our bindgen. The serde
1919-// de/serialization is taken care of at the FFI level.
2020-2116/// Endpoint names for device communication.
2217///
2318/// Endpoints denote different contextual communication targets on a device. For instance, for a
···137137#[macro_use]
138138extern crate strum_macros;
139139140140+#[macro_use]
141141+extern crate log;
142142+143143+mod device_config_file;
144144+pub use device_config_file::{load_protocol_configs, save_user_config};
145145+mod device_config_manager;
146146+pub use device_config_manager::*;
140147mod specifier;
141148pub use specifier::*;
142149mod identifiers;
···145152pub use device_definitions::*;
146153mod device_feature;
147154pub use device_feature::*;
148148-mod device_configuration;
149149-pub use device_configuration::*;
150155mod endpoint;
151156pub use endpoint::*;
152157153153-use buttplug_core::errors::ButtplugDeviceError;
154154-use dashmap::DashMap;
155155-use getset::Getters;
156156-use std::{
157157- collections::HashMap,
158158- fmt::{self, Debug},
159159-};
160158161161-#[macro_use]
162162-extern crate log;
163163-164164-#[derive(Default, Clone)]
165165-pub struct DeviceConfigurationManagerBuilder {
166166- communication_specifiers: HashMap<String, Vec<ProtocolCommunicationSpecifier>>,
167167- user_communication_specifiers: DashMap<String, Vec<ProtocolCommunicationSpecifier>>,
168168- base_device_definitions: HashMap<BaseDeviceIdentifier, BaseDeviceDefinition>,
169169- user_device_definitions: DashMap<UserDeviceIdentifier, DeviceDefinition>,
170170-}
171171-172172-impl DeviceConfigurationManagerBuilder {
173173- pub fn communication_specifier(
174174- &mut self,
175175- protocol_name: &str,
176176- specifier: &[ProtocolCommunicationSpecifier],
177177- ) -> &mut Self {
178178- self
179179- .communication_specifiers
180180- .entry(protocol_name.to_owned())
181181- .or_default()
182182- .extend(specifier.iter().cloned());
183183- self
184184- }
185185-186186- pub fn protocol_features(
187187- &mut self,
188188- identifier: &BaseDeviceIdentifier,
189189- features: &BaseDeviceDefinition,
190190- ) -> &mut Self {
191191- self
192192- .base_device_definitions
193193- .insert(identifier.clone(), features.clone());
194194- self
195195- }
196196-197197- pub fn user_communication_specifier(
198198- &mut self,
199199- protocol_name: &str,
200200- specifier: &[ProtocolCommunicationSpecifier],
201201- ) -> &mut Self {
202202- self
203203- .user_communication_specifiers
204204- .entry(protocol_name.to_owned())
205205- .or_default()
206206- .extend(specifier.iter().cloned());
207207- self
208208- }
209209-210210- pub fn user_protocol_features(
211211- &mut self,
212212- identifier: &UserDeviceIdentifier,
213213- features: &UserDeviceDefinition,
214214- ) -> &mut Self {
215215- if let Some((_, base_definition)) = self
216216- .base_device_definitions
217217- .iter()
218218- .find(|(_, x)| x.id() == features.base_id())
219219- {
220220- self.user_device_definitions.insert(
221221- identifier.clone(),
222222- DeviceDefinition::new(base_definition, features),
223223- );
224224- } else {
225225- error!(
226226- "Cannot find protocol with base id {} for user id {}",
227227- features.base_id(),
228228- features.id()
229229- )
230230- }
231231- self
232232- }
233233-234234- pub fn finish(&mut self) -> Result<DeviceConfigurationManager, ButtplugDeviceError> {
235235- // Build and validate the protocol attributes tree.
236236- let mut attribute_tree_map = HashMap::new();
237237-238238- // Add all the defaults first, they won't have parent attributes.
239239- for (ident, attr) in &self.base_device_definitions {
240240- /*
241241- for feature in attr.features() {
242242- if let Err(e) = feature.is_valid() {
243243- error!("Feature {attr:?} for ident {ident:?} is not valid, skipping addition: {e:?}");
244244- continue;
245245- }
246246- }
247247- */
248248- attribute_tree_map.insert(ident.clone(), attr.clone());
249249- }
250250-251251- let user_attribute_tree_map = DashMap::new();
252252- // Finally, add in user configurations, which will have an address.
253253- for kv in &self.user_device_definitions {
254254- let (ident, attr) = (kv.key(), kv.value());
255255- for feature in attr.features() {
256256- if let Err(e) = feature.is_valid() {
257257- error!("Feature {attr:?} for ident {ident:?} is not valid, skipping addition: {e:?}");
258258- continue;
259259- }
260260- }
261261- user_attribute_tree_map.insert(kv.key().clone(), kv.value().clone());
262262- }
263263-264264- Ok(DeviceConfigurationManager {
265265- base_communication_specifiers: self.communication_specifiers.clone(),
266266- user_communication_specifiers: self.user_communication_specifiers.clone(),
267267- base_device_definitions: attribute_tree_map,
268268- user_device_definitions: user_attribute_tree_map,
269269- //protocol_map,
270270- })
271271- }
272272-}
273273-274274-/// Correlates information about protocols and which devices they support.
275275-///
276276-/// The [DeviceConfigurationManager] handles stores information about which device protocols the
277277-/// library supports, as well as which devices can use those protocols. When a
278278-/// [DeviceCommunicationManager](crate::server::device::communication_manager) finds a device during scanning,
279279-/// device information is given to the [DeviceConfigurationManager] to decide whether Buttplug
280280-/// should try to connect to and communicate with the device.
281281-///
282282-/// Assuming the device is supported by the library, the [DeviceConfigurationManager] also stores
283283-/// information about what commands can be sent to the device (Vibrate, Rotate, etc...), and the
284284-/// parameters for those commands (number of power levels, stroke distances, etc...).
285285-#[derive(Getters)]
286286-#[getset(get = "pub")]
287287-pub struct DeviceConfigurationManager {
288288- /// Communication specifiers from the base device config, mapped from protocol name to vector of
289289- /// specifiers. Should not change/update during a session.
290290- base_communication_specifiers: HashMap<String, Vec<ProtocolCommunicationSpecifier>>,
291291- /// Device definitions from the base device config. Should not change/update during a session.
292292- base_device_definitions: HashMap<BaseDeviceIdentifier, BaseDeviceDefinition>,
293293- /// Communication specifiers provided by the user, mapped from protocol name to vector of
294294- /// specifiers. Loaded at session start, may change over life of session.
295295- user_communication_specifiers: DashMap<String, Vec<ProtocolCommunicationSpecifier>>,
296296- /// Device definitions from the user device config. Loaded at session start, may change over life
297297- /// of session.
298298- user_device_definitions: DashMap<UserDeviceIdentifier, DeviceDefinition>,
299299-}
300300-301301-impl Debug for DeviceConfigurationManager {
302302- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
303303- f.debug_struct("DeviceConfigurationManager").finish()
304304- }
305305-}
306306-307307-impl Default for DeviceConfigurationManager {
308308- fn default() -> Self {
309309- // Unwrap allowed here because we assume our built in device config will
310310- // always work. System won't pass tests or possibly even build otherwise.
311311- DeviceConfigurationManagerBuilder::default()
312312- .finish()
313313- .expect("Default creation of a DCM should always work.")
314314- }
315315-}
316316-317317-impl DeviceConfigurationManager {
318318- pub fn add_user_communication_specifier(
319319- &self,
320320- protocol: &str,
321321- specifier: &ProtocolCommunicationSpecifier,
322322- ) -> Result<(), ButtplugDeviceError> {
323323- //self.protocol_map.contains_key(protocol);
324324- self
325325- .user_communication_specifiers
326326- .entry(protocol.to_owned())
327327- .or_default()
328328- .push(specifier.clone());
329329- Ok(())
330330- }
331331-332332- pub fn remove_user_communication_specifier(
333333- &self,
334334- protocol: &str,
335335- specifier: &ProtocolCommunicationSpecifier,
336336- ) {
337337- if let Some(mut specifiers) = self.user_communication_specifiers.get_mut(protocol) {
338338- let specifier_vec = specifiers.value_mut();
339339- *specifier_vec = specifier_vec
340340- .iter()
341341- .filter(|s| *specifier != **s)
342342- .cloned()
343343- .collect();
344344- }
345345- }
346346-347347- pub fn add_user_device_definition(
348348- &self,
349349- identifier: &UserDeviceIdentifier,
350350- definition: &DeviceDefinition,
351351- ) -> Result<(), ButtplugDeviceError> {
352352- //self.protocol_map.contains_key(identifier.protocol());
353353- // Check validity of device
354354- let mut index = definition.user_config().index();
355355- let indexes: Vec<u32> = self.user_device_definitions().iter().map(|x| x.value().user_config().index()).collect();
356356- // If we just added 1 to the maximum value of the current indexes, someone decides to set an
357357- // index to u32::MAX-1, then we'd have a problem. This is kind of a shit solution but it'll work
358358- // quickly for anyone that's not actively fucking with us by manually playing with user config files.
359359- while indexes.contains(&index) {
360360- index = index.wrapping_add(1);
361361- }
362362- let mut def = definition.clone();
363363- *def.user_device_mut().user_config_mut().index_mut() = index;
364364- self
365365- .user_device_definitions
366366- .entry(identifier.clone())
367367- .insert(def);
368368- Ok(())
369369- }
370370-371371- pub fn remove_user_device_definition(&self, identifier: &UserDeviceIdentifier) {
372372- self.user_device_definitions.remove(identifier);
373373- }
374374-375375- pub fn address_allowed(&self, address: &str) -> bool {
376376- // Make sure the device isn't on the deny list
377377- if self
378378- .user_device_definitions
379379- .iter()
380380- .any(|kv| kv.key().address() == address && kv.value().user_config().deny())
381381- {
382382- // If device is outright denied, deny
383383- info!(
384384- "Device {} denied by configuration, not connecting.",
385385- address
386386- );
387387- false
388388- } else if self
389389- .user_device_definitions
390390- .iter()
391391- .any(|kv| kv.value().user_config().allow())
392392- && !self
393393- .user_device_definitions
394394- .iter()
395395- .any(|kv| kv.key().address() == address && kv.value().user_config().allow())
396396- {
397397- // If device is not on allow list and allow list isn't empty, deny
398398- info!(
399399- "Device {} not on allow list and allow list not empty, not connecting.",
400400- address
401401- );
402402- false
403403- } else {
404404- true
405405- }
406406- }
407407-408408- fn device_index(&self, identifier: &UserDeviceIdentifier) -> u32 {
409409- // See if we have a reserved or reusable device index here.
410410- if let Some(config) = self.user_device_definitions.get(identifier) {
411411- let index = config.user_config().index();
412412- debug!("Found index {index} for device {identifier:?}");
413413- return index;
414414- }
415415-416416- let current_indexes: Vec<u32> = self
417417- .user_device_definitions
418418- .iter()
419419- .map(|x| x.user_config().index())
420420- .collect();
421421-422422- // Someone is gonna make a max device index in their config file just to fuck with me, therefore
423423- // we don't do "max + 1", we fill in holes (lol) in sequences. To whomever has 4 billion sex toys:
424424- // sorry your index finding for new devices is slow and takes 16GB of allocation every time we
425425- // want to search the index space.
426426-427427- let mut index = 0;
428428- while current_indexes.contains(&index) {
429429- index += 1;
430430- }
431431- debug!("Generating and assigning index {index:?} for device {identifier:?}");
432432- index
433433- }
159159+use std::ops::RangeInclusive;
160160+use serde::Serializer;
161161+use thiserror::Error;
434162435435- /// Provides read-only access to the internal protocol/identifier map. Mainly
436436- /// used for WebBluetooth filter construction, but could also be handy for
437437- /// listing capabilities in UI, etc.
438438- pub fn protocol_device_configurations(
439439- &self,
440440- ) -> HashMap<String, Vec<ProtocolCommunicationSpecifier>> {
441441- self.base_communication_specifiers.clone()
442442- }
443443-444444- pub fn device_definition(&self, identifier: &UserDeviceIdentifier) -> Option<DeviceDefinition> {
445445- let features = if let Some(attrs) = self.user_device_definitions.get(identifier) {
446446- debug!("User device config found for {:?}", identifier);
447447- attrs.clone()
448448- } else if let Some(attrs) = self.base_device_definitions.get(&BaseDeviceIdentifier::new(
449449- identifier.protocol(),
450450- identifier.identifier(),
451451- )) {
452452- debug!(
453453- "Protocol + Identifier device config found for {:?}",
454454- identifier
455455- );
456456- DeviceDefinition::new_from_base_definition(attrs, self.device_index(identifier))
457457- } else if let Some(attrs) = self
458458- .base_device_definitions
459459- .get(&BaseDeviceIdentifier::new(identifier.protocol(), &None))
460460- {
461461- debug!("Protocol device config found for {:?}", identifier);
462462- DeviceDefinition::new_from_base_definition(attrs, self.device_index(identifier))
463463- } else {
464464- return None;
465465- };
466466-467467- // If this is a new device, it needs to be added to the user device definition map.
468468- //
469469- // Device definitions are looked up before we fully initialize a device, mostly for algorithm
470470- // preparation. There is a very small chance we may save the device config then error out when
471471- // we connect to the device, but we'll assume we may connect successfully later.
472472- if self.user_device_definitions.get(identifier).is_none() {
473473- self
474474- .user_device_definitions
475475- .insert(identifier.clone(), features.clone());
476476- }
477477-478478- Some(features)
479479- }
163163+#[derive(Error, Debug)]
164164+pub enum ButtplugDeviceConfigError<T> {
165165+ /// Conversion to client type not possible with requested property type
166166+ #[error("Conversion of {0} to client type not possible with requested property type")]
167167+ InvalidOutputTypeConversion(String),
168168+ /// User set range exceeds bounds of possible configuration range
169169+ #[error("User set range {0} exceeds bounds of possible configuration range {1}")]
170170+ InvalidUserRange(RangeInclusive<T>, RangeInclusive<T>),
171171+ /// Base range required
172172+ #[error("Base range required for all feature outputs")]
173173+ BaseRangeRequired,
480174}
···1111use std::collections::{HashMap, HashSet};
1212use uuid::Uuid;
13131414-// Note: There's a ton of extra structs in here just to deserialize the json
1515-// file. Just leave them and build extras (for instance,
1616-// DeviceProtocolConfiguration) if needed elsewhere in the codebase. It's not
1717-// gonna hurt anything and making a ton of serde attributes is just going to get
1818-// confusing (see the messages impl).
1919-2014#[derive(Serialize, Deserialize, Debug, Clone, Getters, MutGetters, Setters, Eq)]
2115#[getset(get = "pub", set = "pub", get_mut = "pub(crate)")]
2216pub struct BluetoothLEManufacturerData {