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
use super::SerialPortDeviceImplCreator;
use crate::{
  core::ButtplugResultFuture,
  server::comm_managers::{
    DeviceCommunicationEvent, DeviceCommunicationManager, DeviceCommunicationManagerCreator,
  },
};
use async_channel::Sender;
use futures::future;
use serialport::available_ports;

pub struct SerialPortCommunicationManager {
  sender: Sender<DeviceCommunicationEvent>,
}

impl DeviceCommunicationManagerCreator for SerialPortCommunicationManager {
  fn new(sender: Sender<DeviceCommunicationEvent>) -> Self {
    info!("Serial port created!");
    Self { sender }
  }
}

impl DeviceCommunicationManager for SerialPortCommunicationManager {
  fn name(&self) -> &'static str {
    "SerialPortCommunicationManager"
  }

  fn start_scanning(&self) -> ButtplugResultFuture {
    info!("Scanning ports!");
    // TODO Does this block? Should it run in one of our threads?
    let sender = self.sender.clone();
    Box::pin(async move {
      match available_ports() {
        Ok(ports) => {
          info!("Got {} serial ports back", ports.len());
          for p in ports {
            info!("{:?}", p);
            sender
              .send(DeviceCommunicationEvent::DeviceFound(Box::new(
                SerialPortDeviceImplCreator::new(&p),
              )))
              .await;
          }
        }
        Err(_) => {
          info!("No serial ports found");
        }
      }
      Ok(())
    })
  }

  fn stop_scanning(&self) -> ButtplugResultFuture {
    Box::pin(future::ready(Ok(())))
  }
}