1use crate::engine::device::SkfDeviceImpl;
2use crate::engine::symbol::ModMag;
3use crate::error::SkfErr;
4use crate::helper::{mem, param};
5use crate::{DeviceManager, PluginEvent, SkfDevice};
6use crate::{Error, Result};
7use skf_api::native::error::SAR_OK;
8use skf_api::native::types::{BOOL, CHAR, HANDLE, ULONG};
9use std::fmt::Debug;
10use std::sync::Arc;
11use tracing::{instrument, trace};
12
13pub(crate) struct ManagerImpl {
14 lib: Arc<libloading::Library>,
15 symbols: ModMag,
16}
17
18impl ManagerImpl {
19 pub fn new(lib: &Arc<libloading::Library>) -> Result<Self> {
23 let lc = Arc::clone(lib);
24 let symbols = ModMag::load_symbols(lib)?;
25 Ok(Self { lib: lc, symbols })
26 }
27}
28
29impl Debug for ManagerImpl {
30 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
31 write!(f, "ManagerImpl")
32 }
33}
34
35impl DeviceManager for ManagerImpl {
36 #[instrument]
37 fn enumerate_device_name(&self, presented_only: bool) -> Result<Vec<String>> {
38 let func = self.symbols.enum_dev.as_ref().expect("Symbol not load");
39 let mut len: ULONG = 0;
40 let ret = unsafe { func(presented_only as BOOL, std::ptr::null_mut(), &mut len) };
41 if ret != SAR_OK {
42 return Err(Error::Skf(SkfErr::of_code(ret)));
43 }
44 trace!("[SKF_EnumDev]: desired len = {}", len);
45 if len == 0 {
46 return Ok(vec![]);
47 }
48 let mut buff = Vec::<CHAR>::with_capacity(len as usize);
49 let ret = unsafe { func(presented_only as BOOL, buff.as_mut_ptr(), &mut len) };
50 trace!("[SKF_EnumDev]: ret = {}", ret);
51 if ret != SAR_OK {
52 return Err(Error::Skf(SkfErr::of_code(ret)));
53 }
54 unsafe { buff.set_len(len as usize) };
55 trace!(
56 "[SKF_EnumDev]: device list = {}",
57 String::from_utf8_lossy(&buff)
58 );
59 let list = unsafe { mem::parse_cstr_list_lossy(buff.as_ptr(), buff.len()) };
61 Ok(list)
62 }
63
64 #[instrument]
65 fn device_state(&self, device_name: &str) -> Result<u32> {
66 let func = self
67 .symbols
68 .get_dev_state
69 .as_ref()
70 .expect("Symbol not load");
71 let device_name = param::as_cstring("device_name", device_name)?;
72 let mut satate: ULONG = 0;
73 let ret = unsafe { func(device_name.as_ptr() as *const CHAR, &mut satate) };
74 if ret != SAR_OK {
75 return Err(Error::Skf(SkfErr::of_code(ret)));
76 }
77 Ok(satate as u32)
78 }
79
80 #[instrument]
81 fn wait_plug_event(&self) -> Result<Option<PluginEvent>> {
82 let func = self
83 .symbols
84 .wait_plug_event
85 .as_ref()
86 .expect("Symbol not load");
87 let mut buff = Vec::<CHAR>::with_capacity(1024);
88 let mut len: ULONG = buff.capacity() as ULONG;
89 let mut event: ULONG = 0;
90 let ret = unsafe { func(buff.as_mut_ptr(), &mut len, &mut event) };
91 trace!("[SKF_WaitForDevEvent]: ret = {}", ret);
92 if ret != SAR_OK {
93 return Err(Error::Skf(SkfErr::of_code(ret)));
94 }
95 trace!(
96 "[SKF_WaitForDevEvent]: event = {},data len = {}",
97 event,
98 len
99 );
100 let name = unsafe { mem::parse_cstr_lossy(buff.as_ptr(), len as usize) };
101 let name = name.unwrap_or("".to_string());
102 let event = event as u8;
103 match event {
104 PluginEvent::EVENT_PLUGGED_IN | PluginEvent::EVENT_UNPLUGGED => {
105 Ok(Some(PluginEvent::new(name, event)))
106 }
107 _ => Ok(None),
108 }
109 }
110
111 #[instrument]
112 fn cancel_wait_plug_event(&self) -> Result<()> {
113 let func = self
114 .symbols
115 .cancel_wait_plug_event
116 .as_ref()
117 .expect("Symbol not load");
118 let ret = unsafe { func() };
119 trace!("[SKF_CancelWaitForDevEvent]: ret = {}", ret);
120 if ret != SAR_OK {
121 return Err(Error::Skf(SkfErr::of_code(ret)));
122 }
123 Ok(())
124 }
125
126 #[instrument]
127 fn connect(&self, device_name: &str) -> Result<Box<dyn SkfDevice>> {
128 let func = self.symbols.connect_dev.as_ref().expect("Symbol not load");
129 let c_name = param::as_cstring("device_name", device_name)?;
130 let mut handle: HANDLE = std::ptr::null_mut();
131 let ret = unsafe { func(c_name.as_ptr() as *const CHAR, &mut handle) };
132 trace!("[SKF_ConnectDev]: ret = {}", ret);
133 if ret != SAR_OK {
134 return Err(Error::Skf(SkfErr::of_code(ret)));
135 }
136 let dev = SkfDeviceImpl::new(handle, device_name, &self.lib)?;
137 Ok(Box::new(dev))
138 }
139
140 fn connect_selected(
141 &self,
142 selector: fn(Vec<&str>) -> Option<&str>,
143 ) -> Result<Box<dyn SkfDevice>> {
144 let list = self.enumerate_device_name(true)?;
145 if list.is_empty() {
146 Err(Error::NotFound("No device found".to_string()))
147 } else {
148 let names: Vec<&str> = list.iter().map(|x| &**x).collect();
149 if let Some(name) = selector(names) {
150 let dev = self.connect(name)?;
151 return Ok(dev);
152 }
153 Err(Error::NotFound("No matched device".to_string()))
154 }
155 }
156}
157
158impl PluginEvent {
159 pub const EVENT_PLUGGED_IN: u8 = 1;
161
162 pub const EVENT_UNPLUGGED: u8 = 2;
164
165 pub fn new(device_name: impl Into<String>, event: u8) -> Self {
166 Self {
167 device_name: device_name.into(),
168 event,
169 }
170 }
171
172 pub fn plugged_in(device_name: impl AsRef<str>) -> Self {
173 Self {
174 device_name: device_name.as_ref().to_string(),
175 event: Self::EVENT_PLUGGED_IN,
176 }
177 }
178
179 pub fn unplugged(device_name: impl AsRef<str>) -> Self {
180 Self {
181 device_name: device_name.as_ref().to_string(),
182 event: Self::EVENT_UNPLUGGED,
183 }
184 }
185
186 pub fn is_plugged_in(&self) -> bool {
187 self.event == Self::EVENT_PLUGGED_IN
188 }
189
190 pub fn is_unplugged(&self) -> bool {
191 self.event == Self::EVENT_UNPLUGGED
192 }
193
194 pub fn event_description(&self) -> &'static str {
195 match self.event {
196 Self::EVENT_PLUGGED_IN => "plugged in",
197 Self::EVENT_UNPLUGGED => "unplugged",
198 _ => "unknown",
199 }
200 }
201}