diff --git a/conUDS/src/arguments.rs b/conUDS/src/arguments.rs index 0f7a50b..4f1b3d9 100644 --- a/conUDS/src/arguments.rs +++ b/conUDS/src/arguments.rs @@ -29,6 +29,7 @@ pub enum ArgSubCommands { Download(SubArgDownload), Reset(SubArgReset), BootloaderDownload(SubArgBootloaderDownload), + ReadDID(SubArgReadDID), } /// Download an application to an ECU @@ -57,3 +58,11 @@ pub struct SubArgReset { #[argh(option, short = 't', default = "SupportedResetTypes::Hard")] pub reset_type: SupportedResetTypes, } + +/// Read a DID from an ECU +#[derive(Debug, FromArgs)] +#[argh(subcommand, name = "readDID")] +pub struct SubArgReadDID { + #[argh(positional)] + pub id: String, +} diff --git a/conUDS/src/main.rs b/conUDS/src/main.rs index 813dbc2..1e4a74d 100644 --- a/conUDS/src/main.rs +++ b/conUDS/src/main.rs @@ -144,6 +144,14 @@ async fn main() -> Result<()> { error!("While downloading app: {}", e); } } + ArgSubCommands::ReadDID(did) => { + debug!( + "Performing DID read on {:#?} for node `{}`", + did, args.node + ); + let id = u16::from_str_radix(&did.id, 16).unwrap(); + let _ = uds_client.did_read(id).await; + } } app.lock().unwrap().exit = true; diff --git a/conUDS/src/modules/uds.rs b/conUDS/src/modules/uds.rs index 7fd342c..6982f7a 100644 --- a/conUDS/src/modules/uds.rs +++ b/conUDS/src/modules/uds.rs @@ -52,6 +52,47 @@ impl UdsClient { .await?) } + pub async fn did_read(&mut self, did: u16) -> Result<()> { + let id: [u8; 2] = [ + (did & 0xff).try_into().unwrap(), + (did >> 8).try_into().unwrap(), + ]; + let buf: [u8; 3] = [ + UdsCommand::ReadDataByIdentifier.into(), + id[0], + id[1], + ]; + + info!("Sending ECU read DID command: {:02x?}", buf); + + match CanioCmd::send_recv(&buf, self.uds_queue_tx.clone(), 50) + .await? + .await + { + Ok(resp) => { + if resp.len() == 2 { + let nrc = UdsErrorByte::from(*resp.last().unwrap()); + if nrc == ecu_diagnostics::Standard(UdsError::ServiceNotSupported) { + error!("Read DID not supported by ECU."); + } + else { + info!("ECU Read DID results: {:02x?}", resp); + } + } + else { + let app_id = u8::from(*resp.last().unwrap()); + info!("ECU Read DID results: {:02x?}", resp); + info!("App ID: {:01x?}", app_id); + } + }, + Err(e) => { + error!("When waiting for response from ECU: {}", e); + return Err(e.into()); + } + } + Ok(()) + } + pub async fn ecu_reset(&mut self, reset_type: SupportedResetTypes) -> Result<()> { let buf = [ UdsCommand::ECUReset.into(),