1#[macro_use]
2extern crate bitflags;
3use std::{fmt::Display, convert::TryFrom};
4
5#[repr(u32)]
9#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
10#[allow(non_camel_case_types, dead_code)]
11pub enum Protocol {
12 J1850VPW = 0x01,
13 J1850PWM = 0x02,
14 ISO9141 = 0x03,
15 ISO14230 = 0x04,
16 CAN = 0x05,
17 ISO15765 = 0x06,
18 SCI_A_ENGINE = 0x07,
19 SCI_A_TRANS = 0x08,
20 SCI_B_ENGINE = 0x09,
21 SCI_B_TRANS = 0x0A,
22}
23
24impl TryFrom<u32> for Protocol {
25 type Error = ();
26
27 fn try_from(value: u32) -> Result<Self, Self::Error> {
28 Ok(match value {
29 0x01 => Protocol::J1850VPW,
30 0x02 => Protocol::J1850PWM,
31 0x03 => Protocol::ISO9141,
32 0x04 => Protocol::ISO14230,
33 0x05 => Protocol::CAN,
34 0x06 => Protocol::ISO15765,
35 0x07 => Protocol::SCI_A_ENGINE,
36 0x08 => Protocol::SCI_A_TRANS,
37 0x09 => Protocol::SCI_B_ENGINE,
38 0x0A => Protocol::SCI_B_TRANS,
39 _ => return Err(())
40 })
41 }
42}
43
44impl Display for Protocol {
45 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46 f.write_str(match &self {
47 Protocol::J1850VPW => "J1850 VPW",
48 Protocol::J1850PWM => "J1850 PWM",
49 Protocol::ISO9141 => "ISO 9141",
50 Protocol::ISO14230 => "ISO 14230",
51 Protocol::CAN => "CAN",
52 Protocol::ISO15765 => "ISO 15765",
53 Protocol::SCI_A_ENGINE => "SCI A ENGINE",
54 Protocol::SCI_A_TRANS => "SCI A TRANS",
55 Protocol::SCI_B_ENGINE => "SCI B ENGINE",
56 Protocol::SCI_B_TRANS => "SCI B TRANS",
57 })
58 }
59}
60
61#[repr(u32)]
62#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
63#[allow(non_camel_case_types, dead_code)]
64pub enum IoctlID {
65 GET_CONFIG = 0x01,
66 SET_CONFIG = 0x02,
67 READ_VBATT = 0x03,
68 FIVE_BAUD_INIT = 0x04,
69 FAST_INIT = 0x05,
70 CLEAR_TX_BUFFER = 0x07,
71 CLEAR_RX_BUFFER = 0x08,
72 CLEAR_PERIODIC_MSGS = 0x09,
73 CLEAR_MSG_FILTERS = 0x0A,
74 CLEAR_FUNCT_MSG_LOOKUP_TABLE = 0x0B,
75 ADD_TO_FUNCT_MSG_LOOKUP_TABLE = 0x0C,
76 DELETE_FROM_FUNCT_MSG_LOOKUP_TABLE = 0x0D,
77 READ_PROG_VOLTAGE = 0x0E,
78}
79
80impl TryFrom<u32> for IoctlID {
81 type Error = ();
82
83 fn try_from(value: u32) -> Result<Self, Self::Error> {
84 Ok(match value {
85 0x01 => IoctlID::GET_CONFIG,
86 0x02 => IoctlID::SET_CONFIG,
87 0x03 => IoctlID::READ_VBATT,
88 0x04 => IoctlID::FIVE_BAUD_INIT,
89 0x05 => IoctlID::FAST_INIT,
90 0x06 => IoctlID::CLEAR_TX_BUFFER,
91 0x07 => IoctlID::CLEAR_RX_BUFFER,
92 0x08 => IoctlID::CLEAR_PERIODIC_MSGS,
93 0x09 => IoctlID::CLEAR_MSG_FILTERS,
94 0x0A => IoctlID::CLEAR_FUNCT_MSG_LOOKUP_TABLE,
95 0x0B => IoctlID::ADD_TO_FUNCT_MSG_LOOKUP_TABLE,
96 0x0D => IoctlID::DELETE_FROM_FUNCT_MSG_LOOKUP_TABLE,
97 0x0E => IoctlID::READ_PROG_VOLTAGE,
98 _ => return Err(())
99 })
100 }
101}
102
103impl std::fmt::Display for IoctlID {
104 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
105 f.write_str(format!("{:?}", self).as_str())
106 }
107}
108
109#[repr(u32)]
110#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
111#[allow(non_camel_case_types, dead_code)]
112pub enum IoctlParam {
113 DATA_RATE = 0x01,
114 LOOPBACK = 0x03,
115
116 NODE_ADDRESS = 0x04,
117 NETWORK_LINE = 0x05,
118 P1_MIN = 0x06,
119 P1_MAX = 0x07,
120 P2_MIN = 0x08,
121 P2_MAX = 0x09,
122 P3_MIN = 0x0A,
123 P3_MAX = 0x0B,
124 P4_MIN = 0x0C,
125 P4_MAX = 0x0D,
126 W1 = 0x0E,
127 W2 = 0x0F,
128 W3 = 0x10,
129 W4 = 0x11,
130 W5 = 0x12,
131
132 TIDLE = 0x13,
133 TINL = 0x14,
134 TWUP = 0x15,
135 PARITY = 0x16,
136 BIT_SAMPLE_POINT = 0x17,
137 SYNCH_JUMP_WIDTH = 0x18,
138 W0 = 0x19,
139 T1_MAX = 0x1A,
140 T2_MAX = 0x1B,
141 T4_MAX = 0x1C,
142 T5_MAX = 0x1D,
143 ISO15765_BS = 0x1E,
144 ISO15765_STMIN = 0x1F,
145
146 DATA_BITS = 0x20,
147 FIVE_BAUD_MOD = 0x21,
148 BS_TX = 0x22,
149 STMIN_TX = 0x23,
150 T3_MAX = 0x24,
151 ISO15765_WFT_MAX = 0x25,
152 CAN_MIXED_FORMAT = 0x8000
153}
154
155impl TryFrom<u32> for IoctlParam {
156 type Error = ();
157
158 fn try_from(value: u32) -> Result<Self, Self::Error> {
159 Ok(match value {
160 0x01 => IoctlParam::DATA_RATE,
161 0x03 => IoctlParam::LOOPBACK,
162 0x04 => IoctlParam::NODE_ADDRESS,
163 0x05 => IoctlParam::NETWORK_LINE,
164 0x06 => IoctlParam::P1_MIN,
165 0x07 => IoctlParam::P1_MAX,
166 0x08 => IoctlParam::P2_MIN,
167 0x09 => IoctlParam::P2_MAX,
168 0x0A => IoctlParam::P3_MIN,
169 0x0B => IoctlParam::P3_MAX,
170 0x0C => IoctlParam::P4_MIN,
171 0x0D => IoctlParam::P4_MAX,
172 0x0E => IoctlParam::W1,
173 0x0F => IoctlParam::W2,
174 0x10 => IoctlParam::W3,
175 0x11 => IoctlParam::W4,
176 0x12 => IoctlParam::W5,
177 0x13 => IoctlParam::TIDLE,
178 0x14 => IoctlParam::TINL,
179 0x15 => IoctlParam::TWUP,
180 0x16 => IoctlParam::PARITY,
181 0x17 => IoctlParam::BIT_SAMPLE_POINT,
182 0x18 => IoctlParam::SYNCH_JUMP_WIDTH,
183 0x19 => IoctlParam::W0,
184 0x1A => IoctlParam::T1_MAX,
185 0x1B => IoctlParam::T2_MAX,
186 0x1C => IoctlParam::T4_MAX,
187 0x1D => IoctlParam::T5_MAX,
188 0x1E => IoctlParam::ISO15765_BS,
189 0x1F => IoctlParam::ISO15765_STMIN,
190 0x20 => IoctlParam::DATA_BITS,
191 0x21 => IoctlParam::FIVE_BAUD_MOD,
192 0x22 => IoctlParam::BS_TX,
193 0x23 => IoctlParam::STMIN_TX,
194 0x24 => IoctlParam::T3_MAX,
195 0x25 => IoctlParam::ISO15765_WFT_MAX,
196 0x8000 => IoctlParam::CAN_MIXED_FORMAT,
197 _ => return Err(())
198 })
199 }
200}
201
202impl std::fmt::Display for IoctlParam {
203 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
204 f.write_str(format!("{:?}", self).as_str())
205 }
206}
207
208#[repr(u32)]
209#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
210#[allow(non_camel_case_types, dead_code)]
211pub enum PassthruError {
212 STATUS_NOERROR = 0x00,
213 ERR_NOT_SUPPORTED = 0x01,
214 ERR_INVALID_CHANNEL_ID = 0x02,
215 ERR_INVALID_PROTOCOL_ID = 0x03,
216 ERR_NULL_PARAMETER = 0x04,
217 ERR_INVALID_IOCTL_VALUE = 0x05,
218 ERR_INVALID_FLAGS = 0x06,
219 ERR_FAILED = 0x07,
220 ERR_DEVICE_NOT_CONNECTED = 0x08,
221 ERR_TIMEOUT = 0x09,
222
223 ERR_INVALID_MSG = 0x0A,
224 ERR_INVALID_TIME_INTERVAL = 0x0B,
225 ERR_EXCEEDED_LIMIT = 0x0C,
226 ERR_INVALID_MSG_ID = 0x0D,
227 ERR_DEVICE_IN_USE = 0x0E,
228 ERR_INVALID_IOCTL_ID = 0x0F,
229 ERR_BUFFER_EMPTY = 0x10,
230 ERR_BUFFER_FULL = 0x11,
231 ERR_BUFFER_OVERFLOW = 0x12,
232 ERR_PIN_INVALID = 0x13,
233 ERR_CHANNEL_IN_USE = 0x14,
234 ERR_MSG_PROTOCOL_ID = 0x15,
235
236 ERR_INVALID_FILTER_ID = 0x16,
237 ERR_NO_FLOW_CONTROL = 0x17,
238 ERR_NOT_UNIQUE = 0x18,
239 ERR_INVALID_BAUDRATE = 0x19,
240 ERR_INVALID_DEVICE_ID = 0x1A,
241}
242
243impl TryFrom<u32> for PassthruError {
244 type Error = ();
245
246 fn try_from(value: u32) -> Result<Self, Self::Error> {
247 Ok(match value {
248 0x00 => PassthruError::STATUS_NOERROR,
249 0x01 => PassthruError::ERR_NOT_SUPPORTED,
250 0x02 => PassthruError::ERR_INVALID_CHANNEL_ID,
251 0x03 => PassthruError::ERR_INVALID_PROTOCOL_ID,
252 0x04 => PassthruError::ERR_NULL_PARAMETER,
253 0x05 => PassthruError::ERR_INVALID_IOCTL_VALUE,
254 0x06 => PassthruError::ERR_INVALID_FLAGS,
255 0x07 => PassthruError::ERR_FAILED,
256 0x08 => PassthruError::ERR_DEVICE_NOT_CONNECTED,
257 0x09 => PassthruError::ERR_TIMEOUT,
258 0x0A => PassthruError::ERR_INVALID_MSG,
259 0x0B => PassthruError::ERR_INVALID_TIME_INTERVAL,
260 0x0C => PassthruError::ERR_EXCEEDED_LIMIT,
261 0x0D => PassthruError::ERR_INVALID_MSG_ID,
262 0x0E => PassthruError::ERR_DEVICE_IN_USE,
263 0x0F => PassthruError::ERR_INVALID_IOCTL_ID,
264 0x10 => PassthruError::ERR_BUFFER_EMPTY,
265 0x11 => PassthruError::ERR_BUFFER_FULL,
266 0x12 => PassthruError::ERR_BUFFER_OVERFLOW,
267 0x13 => PassthruError::ERR_PIN_INVALID,
268 0x14 => PassthruError::ERR_CHANNEL_IN_USE,
269 0x15 => PassthruError::ERR_MSG_PROTOCOL_ID,
270 0x16 => PassthruError::ERR_INVALID_FILTER_ID,
271 0x17 => PassthruError::ERR_NO_FLOW_CONTROL,
272 0x18 => PassthruError::ERR_NOT_UNIQUE,
273 0x19 => PassthruError::ERR_INVALID_BAUDRATE,
274 0x1A => PassthruError::ERR_INVALID_DEVICE_ID,
275 _ => return Err(())
276 })
277 }
278}
279
280impl Display for PassthruError {
281 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
282 f.write_str(match &self {
283 PassthruError::STATUS_NOERROR => "No Error",
284 PassthruError::ERR_NOT_SUPPORTED => "Operation not supported",
285 PassthruError::ERR_INVALID_CHANNEL_ID => "Invalid channel ID",
286 PassthruError::ERR_INVALID_PROTOCOL_ID => "Invalid protocol ID",
287 PassthruError::ERR_NULL_PARAMETER => "Null parameter received",
288 PassthruError::ERR_INVALID_IOCTL_VALUE => "Invalid IOCTL Value",
289 PassthruError::ERR_INVALID_FLAGS => "Invalid flags",
290 PassthruError::ERR_FAILED => "Unspecified error",
291 PassthruError::ERR_DEVICE_NOT_CONNECTED => "Device not connected",
292 PassthruError::ERR_TIMEOUT => "Device timeout",
293 PassthruError::ERR_INVALID_MSG => "Invalid or malformed message",
294 PassthruError::ERR_INVALID_TIME_INTERVAL => "Time interval outside specified range",
295 PassthruError::ERR_EXCEEDED_LIMIT => "Too many filters or periodic messages",
296 PassthruError::ERR_INVALID_MSG_ID => "Message ID / Handle ID not recognized",
297 PassthruError::ERR_DEVICE_IN_USE => "Device is already in use",
298 PassthruError::ERR_INVALID_IOCTL_ID => "IOCTL ID not recognized",
299 PassthruError::ERR_BUFFER_EMPTY => "Receive buffer is empty",
300 PassthruError::ERR_BUFFER_FULL => "Transmit buffer is full",
301 PassthruError::ERR_BUFFER_OVERFLOW => "Device buffer overflow",
302 PassthruError::ERR_PIN_INVALID => "Unknown pin specified",
303 PassthruError::ERR_CHANNEL_IN_USE => "Channel is already in use",
304 PassthruError::ERR_MSG_PROTOCOL_ID => "Message protocol ID does not match that of the communication channel",
305 PassthruError::ERR_INVALID_FILTER_ID => "Filter ID not recognized",
306 PassthruError::ERR_NO_FLOW_CONTROL => "No flow control filter is set",
307 PassthruError::ERR_NOT_UNIQUE => "An existing filter already matches",
308 PassthruError::ERR_INVALID_BAUDRATE => "Unable to set requested baudrate",
309 PassthruError::ERR_INVALID_DEVICE_ID => "Device ID not recognized",
310 })
311 }
312}
313
314#[repr(u32)]
315#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
316#[allow(non_camel_case_types, dead_code)]
317pub enum FilterType {
318 PASS_FILTER = 0x01,
319 BLOCK_FILTER = 0x02,
320 FLOW_CONTROL_FILTER = 0x03,
321}
322
323impl TryFrom<u32> for FilterType {
324 type Error = ();
325
326 fn try_from(value: u32) -> Result<Self, Self::Error> {
327 Ok(match value {
328 0x01 => FilterType::PASS_FILTER,
329 0x02 => FilterType::BLOCK_FILTER,
330 0x03 => FilterType::FLOW_CONTROL_FILTER,
331 _ => return Err(())
332 })
333 }
334}
335
336impl std::fmt::Display for FilterType {
337 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
338 match &self {
339 FilterType::PASS_FILTER => f.write_str("Pass filter"),
340 FilterType::BLOCK_FILTER => f.write_str("Block filter"),
341 FilterType::FLOW_CONTROL_FILTER => f.write_str("ISO-TP flow control filter"),
342 }
343 }
344}
345
346#[repr(u32)]
347#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
348#[allow(non_camel_case_types, dead_code)]
349pub enum LoopBackSetting {
350 OFF = 0x00,
351 ON = 0x01,
352}
353
354#[repr(u32)]
355#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
356#[allow(non_camel_case_types, dead_code)]
357pub enum DataBits {
358 DATA_BITS_8 = 0x00,
359 DATA_BITS_7 = 0x01,
360}
361
362#[repr(u32)]
363#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
364#[allow(non_camel_case_types, dead_code)]
365pub enum ParitySetting {
366 NO_PARITY = 0x00,
367 ODD_PARITY = 0x01,
368 EVEN_PARITY = 0x02,
369}
370
371#[repr(u32)]
372#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
373#[allow(non_camel_case_types, dead_code)]
374pub enum J1850PWMNetworkLine {
375 BUS_NORMAL = 0x00,
376 BUS_PLUS = 0x01,
377 BUS_MINUS = 0x02,
378}
379
380bitflags! {
381 pub struct ConnectFlags: u32 {
382 const CAN_29BIT_ID = 0x00000100;
383 const ISO9141_NO_CHECKSUM = 0x00000200;
384 const CAN_ID_BOTH = 0x00000800;
385 const ISO15765_ADDR_TYPE = 0x00000080;
386 const ISO9141_K_LINE_ONLY = 0x00001000;
387 }
388}
389
390bitflags! {
391 pub struct RxFlag: u32 {
392 const CAN_29BIT_ID = 0x00000100;
393 const ISO15765_ADDR_TYPE = 0x00000080;
394 const ISO15765_PADDING_ERROR = 0x00000010;
395 const TX_DONE = 0x00000008;
396 const RX_BREAK = 0x00000004;
397 const ISO15765_FIRST_FRAME = 0x00000002;
398 const START_OF_MESSAGE = 0x00000002;
399 const TX_MSG_TYPE = 0x00000001;
400 }
401}
402
403bitflags! {
404 pub struct TxFlag: u32 {
405 const SCI_TX_VOLTAGE = 0x00800000;
406 const SCI_MODE = 0x00400000;
407 const BLOCKING = 0x00010000;
408 const WAIT_P3_MIN_ONLY = 0x00000200;
409 const CAN_29BIT_ID = 0x00000100;
410 const CAN_EXTENDED_ID = 0x00000100;
411 const ISO15765_ADDR_TYPE = 0x00000080;
412 const ISO15765_EXT_ADDR = 0x00000080;
413 const ISO15765_FRAME_PAD = 0x00000040;
414 const TX_NORMAL_TRANSMIT = 0x00000000;
415 }
416}
417
418#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
419#[repr(C)]
420pub struct PASSTHRU_MSG {
421 pub protocol_id: u32,
422 pub rx_status: u32,
423 pub tx_flags: u32,
424 pub timestamp: u32,
425 pub data_size: u32,
426 pub extra_data_size: u32,
427 pub data: [u8; 4128],
428}
429
430impl Default for PASSTHRU_MSG {
431 fn default() -> Self {
432 PASSTHRU_MSG {
433 protocol_id: 0,
434 rx_status: 0,
435 tx_flags: 0,
436 timestamp: 0,
437 data_size: 0,
438 extra_data_size: 0,
439 data: [0; 4128],
440 }
441 }
442}
443
444impl std::fmt::Display for PASSTHRU_MSG {
445 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
446 f.write_str(format!(
447 "Protocol: {}, RxStatus: {:08X}, TxFlags: {:08X}, Data: {:02X?}",
448 Protocol::try_from(self.protocol_id).unwrap(),
449 self.rx_status,
450 self.tx_flags,
451 &self.data[0..self.data_size as usize]
452
453 ).as_str())
454 }
455}
456
457#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
458#[repr(C)]
459pub struct SBYTE_ARRAY {
460 pub num_of_bytes: u32,
461 pub byte_ptr: *mut u8,
462}
463
464#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
465#[repr(C)]
466pub struct SConfig {
467 pub parameter: u32,
468 pub value: u32,
469}
470
471#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
472#[repr(C)]
473pub struct SConfigList {
474 pub num_of_params: u32,
475 pub config_ptr: *mut SConfig,
476}