use crate::dynamic_diag::DynamicDiagSession;
use crate::obd2::decode_pid_response;
use crate::{DiagError, DiagServerResult};
use automotive_diag::obd2::{Obd2Command, Service09Pid, Service09PidByte};
use automotive_diag::ByteWrapper::{Extended, Standard};
#[derive(Debug)]
pub struct Service09<'a> {
server: &'a DynamicDiagSession,
support_list: Vec<bool>,
}
impl DynamicDiagSession {
pub fn obd_init_service_09(&self) -> DiagServerResult<Service09> {
let pid_support_list = self.send_command_with_response(Obd2Command::Service09, &[0x00])?;
Ok(Service09 {
server: self,
support_list: decode_pid_response(&pid_support_list[2..]),
})
}
}
impl<'a> Service09<'a> {
pub fn get_supported_sids(&self) -> Vec<Service09PidByte> {
let mut r = Vec::new();
for (pid, supported) in self.support_list.iter().enumerate() {
if *supported {
r.push(match pid + 1 {
0x01 => Standard(Service09Pid::VinMsgCount),
0x02 => Standard(Service09Pid::Vin),
0x03 => Standard(Service09Pid::CalibrationIDMsgCount),
0x04 => Standard(Service09Pid::CalibrationID),
0x05 => Standard(Service09Pid::CvnMsgCount),
0x06 => Standard(Service09Pid::Cvn),
0x08 => Standard(Service09Pid::InUsePerfTracking),
0x09 => Standard(Service09Pid::EcuNameMsgCount),
0x0A => Standard(Service09Pid::EcuName),
x => Extended(x as u8),
})
}
}
r
}
pub fn read_vin(&self) -> DiagServerResult<String> {
if !self.support_list[0x01] {
return Err(DiagError::NotSupported); }
let resp = self
.server
.send_command_with_response(Obd2Command::Service09, &[0x02])?;
Ok(
String::from_utf8_lossy(resp.get(3..).ok_or(DiagError::InvalidResponseLength)?)
.into_owned(),
)
}
pub fn read_calibration_id(&self) -> DiagServerResult<Vec<String>> {
if !self.support_list[0x03] {
return Err(DiagError::NotSupported); }
let mut resp = self
.server
.send_command_with_response(Obd2Command::Service09, &[0x04])?;
resp.drain(0..3);
return Ok(resp
.chunks(16)
.map(|c| String::from_utf8_lossy(c).to_string())
.collect());
}
pub fn read_cvn(&self) -> DiagServerResult<Vec<String>> {
if !self.support_list[0x05] {
return Err(DiagError::NotSupported); }
let mut resp = self
.server
.send_command_with_response(Obd2Command::Service09, &[0x06])?;
resp.drain(0..3);
return Ok(resp
.chunks(4)
.map(|c| format!("{:02X}{:02X}{:02X}{:02X}", c[0], c[1], c[2], c[3]))
.collect());
}
}