1use crate::{Connection, ConnectionType, bluetooth, serial};
2use futures::{TryFutureExt, try_join};
3use std::time::Duration;
4use thiserror::Error;
5use vex_cdc::{Decode, DecodeError, Encode, FixedStringSizeError, cdc2::Cdc2Ack};
6
7use super::{CheckHeader, bluetooth::BluetoothError, serial::SerialError};
8
9pub enum GenericConnection {
10 Bluetooth(bluetooth::BluetoothConnection),
11 Serial(serial::SerialConnection),
12}
13impl Connection for GenericConnection {
14 type Error = GenericError;
15
16 fn connection_type(&self) -> ConnectionType {
17 match self {
18 GenericConnection::Bluetooth(_) => ConnectionType::Bluetooth,
19 GenericConnection::Serial(s) => s.connection_type(),
20 }
21 }
22
23 async fn send(&mut self, packet: impl Encode) -> Result<(), GenericError> {
24 match self {
25 GenericConnection::Bluetooth(c) => c.send(packet).await?,
26 GenericConnection::Serial(s) => s.send(packet).await?,
27 };
28 Ok(())
29 }
30
31 async fn recv<P: Decode + CheckHeader>(
32 &mut self,
33 timeout: std::time::Duration,
34 ) -> Result<P, GenericError> {
35 Ok(match self {
36 GenericConnection::Bluetooth(c) => c.recv(timeout).await?,
37 GenericConnection::Serial(s) => s.recv(timeout).await?,
38 })
39 }
40
41 async fn read_user(&mut self, buf: &mut [u8]) -> Result<usize, GenericError> {
42 Ok(match self {
43 GenericConnection::Bluetooth(c) => c.read_user(buf).await?,
44 GenericConnection::Serial(s) => s.read_user(buf).await?,
45 })
46 }
47
48 async fn write_user(&mut self, buf: &[u8]) -> Result<usize, GenericError> {
49 Ok(match self {
50 GenericConnection::Bluetooth(c) => c.write_user(buf).await?,
51 GenericConnection::Serial(s) => s.write_user(buf).await?,
52 })
53 }
54}
55impl GenericConnection {
56 pub fn is_bluetooth(&self) -> bool {
58 self.connection_type().is_bluetooth()
59 }
60 pub fn is_wired(&self) -> bool {
62 self.connection_type().is_wired()
63 }
64 pub fn is_controller(&self) -> bool {
66 self.connection_type().is_controller()
67 }
68
69 pub async fn is_paired(&self) -> Result<bool, GenericError> {
72 match self {
73 GenericConnection::Bluetooth(c) => Ok(c.is_paired().await?),
74 GenericConnection::Serial(_) => Err(GenericError::PairingNotSupported),
75 }
76 }
77
78 pub async fn request_pairing(&mut self) -> Result<(), GenericError> {
83 match self {
84 GenericConnection::Bluetooth(c) => Ok(c.request_pairing().await?),
85 GenericConnection::Serial(_) => Err(GenericError::PairingNotSupported),
86 }
87 }
88
89 pub async fn authenticate_pairing(&mut self, pin: [u8; 4]) -> Result<(), GenericError> {
92 match self {
93 GenericConnection::Bluetooth(c) => Ok(c.authenticate_pairing(pin).await?),
94 GenericConnection::Serial(_) => Err(GenericError::PairingNotSupported),
95 }
96 }
97}
98
99impl From<bluetooth::BluetoothConnection> for GenericConnection {
100 fn from(c: bluetooth::BluetoothConnection) -> Self {
101 GenericConnection::Bluetooth(c)
102 }
103}
104impl From<serial::SerialConnection> for GenericConnection {
105 fn from(c: serial::SerialConnection) -> Self {
106 GenericConnection::Serial(c)
107 }
108}
109
110#[derive(Debug, Clone)]
111pub enum GenericDevice {
112 Bluetooth(bluetooth::BluetoothDevice),
113 Serial(serial::SerialDevice),
114}
115impl GenericDevice {
116 pub async fn connect(&self, timeout: Duration) -> Result<GenericConnection, GenericError> {
117 match self.clone() {
118 GenericDevice::Bluetooth(d) => Ok(GenericConnection::Bluetooth(d.connect().await?)),
119 GenericDevice::Serial(d) => Ok(GenericConnection::Serial(d.connect(timeout)?)),
120 }
121 }
122}
123impl From<serial::SerialDevice> for GenericDevice {
124 fn from(d: serial::SerialDevice) -> Self {
125 GenericDevice::Serial(d)
126 }
127}
128impl From<bluetooth::BluetoothDevice> for GenericDevice {
129 fn from(d: bluetooth::BluetoothDevice) -> Self {
130 GenericDevice::Bluetooth(d)
131 }
132}
133
134pub async fn find_devices() -> Result<Vec<GenericDevice>, GenericError> {
135 let res = try_join! {
136 bluetooth_devices().map_err(GenericError::BluetoothError),
137 serial_devices().map_err(GenericError::SerialError),
138 }
139 .map(|(bluetooth, serial)| bluetooth.into_iter().chain(serial.into_iter()).collect())?;
140 Ok(res)
141}
142
143async fn bluetooth_devices() -> Result<Vec<GenericDevice>, BluetoothError> {
144 let devices = bluetooth::find_devices(Duration::from_secs(10), None).await?;
146 let devices = devices.into_iter().map(GenericDevice::Bluetooth).collect();
147 Ok(devices)
148}
149
150async fn serial_devices() -> Result<Vec<GenericDevice>, SerialError> {
151 let devices = serial::find_devices()?;
152 let devices = devices.into_iter().map(GenericDevice::Serial).collect();
153 Ok(devices)
154}
155
156#[derive(Error, Debug)]
157pub enum GenericError {
158 #[error("Serial Error: {0}")]
159 SerialError(#[from] SerialError),
160 #[error("Bluetooth Error: {0}")]
161 BluetoothError(#[from] BluetoothError),
162 #[error("Packet decoding error: {0}")]
163 DecodeError(#[from] DecodeError),
164 #[error("NACK received: {0:?}")]
165 Nack(#[from] Cdc2Ack),
166 #[error("Pairing is not supported over any connection other than Bluetooth")]
167 PairingNotSupported,
168 #[error(transparent)]
169 FixedStringSizeError(#[from] FixedStringSizeError),
170}