use crate::dynamic_diag::DynamicDiagSession;
use crate::obd2::units::ObdValue;
use crate::obd2::{decode_pid_response, DataPidWrapper};
use crate::{DiagError, DiagServerResult};
use automotive_diag::obd2::{DataPidByte, Obd2Command};
#[derive(Debug)]
pub struct Service01<'a> {
server: &'a DynamicDiagSession,
support_list: Vec<bool>,
}
impl DynamicDiagSession {
pub fn obd_init_service_01(&self) -> DiagServerResult<Service01> {
let mut total_support_list = Vec::new();
for i in (0..0xFF).step_by(0x20) {
let x = self.send_command_with_response(Obd2Command::Service01, &[i as u8]);
match x {
Ok(resp) => total_support_list.extend_from_slice(&resp[2..]),
Err(e) => {
if let DiagError::ECUError { code: _, def: _ } = e {
total_support_list.extend_from_slice(&[0x00, 0x00, 0x00, 0x00])
} else {
total_support_list.extend_from_slice(&[0x00, 0x00, 0x00, 0x00])
}
}
}
if total_support_list.last().unwrap() & 0x01 == 0 {
break;
}
}
Ok(Service01 {
server: self,
support_list: decode_pid_response(&total_support_list),
})
}
}
impl<'a> Service01<'a> {
pub fn get_supported_pids(&self) -> Vec<DataPidByte> {
let mut r = Vec::new();
for (idx, supported) in self.support_list.iter().enumerate() {
if *supported {
let pid = (idx + 1) as u8;
if !&[0x13, 0x1D, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xE0].contains(&pid) {
r.push(DataPidByte::from(pid))
}
}
}
r
}
pub fn query_pid(&self, pid: DataPidWrapper) -> DiagServerResult<Vec<ObdValue>> {
pid.get_value(&self.server, None)
}
}
#[cfg(test)]
pub mod service_09_test {
use crate::obd2::units::{ObdUnitType, ObdValue};
use crate::DiagServerResult;
fn print_pid(v: DiagServerResult<ObdValue>) {
match v {
Ok(value) => {
if let ObdUnitType::Encoded(e) = value.get_value() {
println!("{} OK! Enum {}", value.get_name(), e)
} else {
println!(
"{} OK! Metric: {}{}, Imperial: {}{}",
value.get_name(),
value.get_metric_data(),
value.get_metric_unit().unwrap_or_default(),
value.get_imperial_data(),
value.get_imperial_unit().unwrap_or_default()
);
}
}
Err(e) => {
eprintln!("PID request failed {e}");
}
}
}
}