uds_rs/uds/
write_data_by_identifier.rs

1//! # Implementation of WriteDataByIdentifier 0x2E service
2//!
3//! This module provides following methods for UdsClient:
4//!
5//! [UdsClient::write_data_by_identifier]
6//!
7
8use crate::uds::uds_definitions::SEND_RECEIVE_SID_OFFSET;
9use crate::uds::{EcuResponseResult, UdsClient, UdsError, UdsResponse};
10use crate::DataFormat;
11
12const WRITE_DATA_BY_IDENTIFIER_SID: u8 = 0x2E;
13
14#[derive(Debug, PartialEq)]
15pub struct WriteDataByIdentifierResponse {
16    data_identifier: u16,
17}
18impl UdsClient {
19    pub async fn write_data_by_identifier(
20        &self,
21        data_identifier: u16,
22        data_record: &[u8],
23    ) -> EcuResponseResult {
24        let request = compose_write_data_by_identifier_request(data_identifier, data_record);
25        let raw_response = self.send_and_receive(&request).await?;
26        let response = parse_write_data_by_identifier_response(&raw_response);
27        response
28    }
29}
30
31fn compose_write_data_by_identifier_request(data_identifier: u16, data_record: &[u8]) -> Vec<u8> {
32    let mut ret = vec![
33        WRITE_DATA_BY_IDENTIFIER_SID,
34        (data_identifier >> 8) as u8,
35        data_identifier as u8,
36    ];
37    ret.extend_from_slice(data_record);
38    ret
39}
40
41fn parse_write_data_by_identifier_response(raw_response: &[u8]) -> EcuResponseResult {
42    let mut response_iter = raw_response.iter();
43    let sid = *response_iter.next().ok_or(UdsError::ResponseEmpty)?;
44    if sid != WRITE_DATA_BY_IDENTIFIER_SID + SEND_RECEIVE_SID_OFFSET {
45        return Err(UdsError::SidMismatch {
46            expected: WRITE_DATA_BY_IDENTIFIER_SID + SEND_RECEIVE_SID_OFFSET,
47            received: sid,
48            raw_message: raw_response.to_vec(),
49        });
50    }
51    let msb = *response_iter.next().ok_or(UdsError::InvalidLength {
52        raw_message: raw_response.to_vec(),
53    })?;
54    let lsb = *response_iter.next().ok_or(UdsError::InvalidLength {
55        raw_message: raw_response.to_vec(),
56    })?;
57    let data_identifier = ((msb as u16) << 8) + lsb as u16;
58    let response =
59        UdsResponse::WriteDataByIdentifier(DataFormat::Parsed(WriteDataByIdentifierResponse {
60            data_identifier,
61        }));
62    Ok(response)
63}