1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
use crate::server::device::configuration::ProtocolDeviceAttributes;
use crate::{
  core::{errors::ButtplugDeviceError, message::Endpoint},
  server::device::{
    configuration::ProtocolAttributesType,
    hardware::{Hardware, HardwareCommand, HardwareReadCmd, HardwareWriteCmd},
    protocol::{ProtocolHandler, ProtocolIdentifier, ProtocolInitializer},
    ServerDeviceIdentifier,
  },
};
use async_trait::async_trait;
use std::sync::Arc;
pub mod setup {
  use crate::server::device::protocol::{ProtocolIdentifier, ProtocolIdentifierFactory};
  #[derive(Default)]
  pub struct HismithIdentifierFactory {}
  impl ProtocolIdentifierFactory for HismithIdentifierFactory {
    fn identifier(&self) -> &str {
      "hismith"
    }
    fn create(&self) -> Box<dyn ProtocolIdentifier> {
      Box::new(super::HismithIdentifier::default())
    }
  }
}
#[derive(Default)]
pub struct HismithIdentifier {}
#[async_trait]
impl ProtocolIdentifier for HismithIdentifier {
  async fn identify(
    &mut self,
    hardware: Arc<Hardware>,
  ) -> Result<(ServerDeviceIdentifier, Box<dyn ProtocolInitializer>), ButtplugDeviceError> {
    let result = hardware
      .read_value(&HardwareReadCmd::new(Endpoint::RxBLEModel, 128, 500))
      .await?;
    let identifier = result
      .data()
      .into_iter()
      .map(|b| format!("{:02x}", b))
      .collect::<String>();
    info!("Hismith Device Identifier: {}", identifier);
    Ok((
      ServerDeviceIdentifier::new(
        hardware.address(),
        "hismith",
        &ProtocolAttributesType::Identifier(identifier),
      ),
      Box::new(HismithInitializer::default()),
    ))
  }
}
#[derive(Default)]
pub struct HismithInitializer {}
#[async_trait]
impl ProtocolInitializer for HismithInitializer {
  async fn initialize(
    &mut self,
    _: Arc<Hardware>,
    _: &ProtocolDeviceAttributes,
  ) -> Result<Arc<dyn ProtocolHandler>, ButtplugDeviceError> {
    Ok(Arc::new(Hismith::default()))
  }
}
#[derive(Default)]
pub struct Hismith {}
impl ProtocolHandler for Hismith {
  fn handle_scalar_oscillate_cmd(
    &self,
    _index: u32,
    scalar: u32,
  ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
    let idx: u8 = if _index == 0 { 0x04 } else { 0x06 };
    let speed: u8 = if _index != 0 && scalar == 0 {
      0xf0
    } else {
      scalar as u8
    };
    Ok(vec![HardwareWriteCmd::new(
      Endpoint::Tx,
      vec![0xAA, idx, speed, speed + idx],
      false,
    )
    .into()])
  }
  fn handle_scalar_vibrate_cmd(
    &self,
    _index: u32,
    scalar: u32,
  ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
    let idx: u8 = if _index == 0 { 0x04 } else { 0x06 };
    let speed: u8 = if _index != 0 && scalar == 0 {
      0xf0
    } else {
      scalar as u8
    };
    Ok(vec![HardwareWriteCmd::new(
      Endpoint::Tx,
      vec![0xAA, idx, speed, speed + idx],
      false,
    )
    .into()])
  }
}