uds-rs 0.3.0

A asynchronous library implementing UDS protocol over CAN used for automotive diagnostic, standardized by ISO 14229-1:2013.
Documentation
//! provides asynchronous UDS communication via socketcan.
//!
//! All communication was designed to be used primarily with ISO 14229-1:2013 definition of UDS.
//!
//! # Example
//!
//! For correct behaviour make sure to set-up a CAN interface first.
//! You an you a virtual CAN interface for testing purposes, for example with the following command.
//! To make setting-up a CAN interface easier install [can-utils-rs](https://crates.io/crates/can-utils-rs) package
//! ```bash
//! cargo install can-utils-rs
//! ```
//! Then use the following command:
//! ```bash
//! can-utils-rs
//! ```
//! Then select the interface type you want to use. Then make sure to match the name of the interface (can0 in the example)
//! with the one you have set-up.
//!
//! ```no_run
//! // To run the example make sure to set-up a CAN interface first!
//!
//! use embedded_can::StandardId;
//! use log::{error, info};
//! use uds_rs::{ResetType, UdsClient, UdsError, UdsSocketOptions};
//!
//! #[tokio::main(flavor = "current_thread")]
//! async fn main() -> Result<(), UdsError> {
//!     env_logger::init();
//!     // Create client wtih default options
//!     let c = UdsClient::new(
//!         "can0",
//!         StandardId::new(0x774).expect("Invalid src id"),
//!         StandardId::new(0x70A).expect("Invalid dst id"),
//!         UdsSocketOptions::default(),
//!     )?;
//!
//!     // read data by identifier (ecu VIN)
//!     let read_data_result = c.read_data_by_identifier(&[0xf18a]).await;
//!     match read_data_result {
//!         Ok(x) => info!("Read data by identifier received {:#x?}", x),
//!         Err(e) => error!(
//!             "Read single data by identifier failed with error: {:#x?}",
//!             e
//!         ),
//!     };
//!
//!     // reading dtc
//!     let read_dtc_information = c.report_dtc_by_status_mask(0xff).await;
//!     match read_dtc_information {
//!         Ok(x) => info!("Read dtc by status mask: {:#x?}", x),
//!         Err(e) => error!("Read dtc by status mask failed with error: {:#x?}", e),
//!     }
//!
//!     // clear all stored dtc
//!     let clear_dtc_information = c.clear_diagnostic_information(0xffffff).await;
//!     match clear_dtc_information {
//!         Ok(x) => info!("{:#x?}", x),
//!         Err(e) => error!("Clear diagnostic information failed with error: {:#x?}", e),
//!     };
//!
//!     // ecu reset
//!     let ecu_reset_result = c.ecu_reset(ResetType::KeyOffOnReset).await;
//!     match ecu_reset_result {
//!         Ok(x) => info!("{:#x?}", x),
//!         Err(e) => error!("Ecu reset failed with error: {:#x?}", e),
//!     };
//!
//!     Ok(())
//! }
//! ```
//!
//! ### Example with specific ISO-TP configuration
//!
//! ```no_run
//! // To run the example make sure to set-up a CAN interface first!
//!
//! use embedded_can::StandardId;
//! use log::{error, info};
//! use uds_rs::{ResetType, UdsClient, UdsError, UdsSocketOptions};
//!
//!
//! #[tokio::main(flavor = "current_thread")]
//! async fn main() -> Result<(), UdsError> {
//!     env_logger::init();
//!     // Create client with VW specific options
//!     let socket_options = UdsSocketOptions::vw()?;
//!     let c = UdsClient::new(
//!         "can0",
//!         StandardId::new(0x774).expect("Invalid src id"),
//!         StandardId::new(0x70A).expect("Invalid dst id"),
//!         socket_options,
//!     )?;
//!
//!     Ok(())
//!
//! }
//! ```
//!
//! # Notes for development
//! ## Communication architecture
//! Current communication architecture is strictly bounded request-response together. It would be
//! much better to have these two interactions separated into queues and adding one producer for writes and one consumer
//! for reads.
//!
//! Without this functionality the services like ReadDataByPeriodicIdentifier cannot be implemented.
//!
//! ## Hierarchy
//!
//! module __uds__ - top module containing UdsClient trough which all interaction is provided for the user
//! services used by UdsClient are stored in separate modules - see for example read_data_by_identifier.rs,
//! where structure of service module is described
//!
//! module __communication__ - basic communication framework. Purpose of this module is to provide send
//! and receive functionality for UdsClient.
//!
//! ## Services implementation
//! each service consists of three steps  
//! __compose function__ - serializing service method arguments and other needed
//! data to Vec\<u8\>  
//! __send and receive__ - passing composed vector as slice to the communication backend and returning raw response  
//! __parse function__ - parsing received raw response &\[u8\] and serializing it into UdsMessage
//!
//! # Notes
//! For the correct behaviour, you need to have Linux kernel with applied patch:
//! <https://lore.kernel.org/linux-can/20230818114345.142983-1-lukas.magel@posteo.net/#r>
pub mod uds;

pub use uds::*;