use heapless::Vec;
use crate::services::diagnostic::{ObjectId, ReadDeviceIdCode, request::ReqPduCompiler};
use mbus_core::{
data_unit::common::{self, MAX_ADU_FRAME_LEN},
errors::MbusError,
function_codes::public::{DiagnosticSubFunction, EncapsulatedInterfaceType},
transport::TransportType,
};
#[derive(Debug, Clone)]
pub struct ServiceBuilder;
impl ServiceBuilder {
pub fn read_device_identification(
txn_id: u16,
unit_id: u8,
read_device_id_code: ReadDeviceIdCode,
object_id: ObjectId,
transport_type: TransportType,
) -> Result<Vec<u8, MAX_ADU_FRAME_LEN>, MbusError> {
let pdu =
ReqPduCompiler::read_device_identification_request(read_device_id_code, object_id)?;
common::compile_adu_frame(txn_id, unit_id, pdu, transport_type)
}
pub fn encapsulated_interface_transport(
txn_id: u16,
unit_id: u8,
mei_type: EncapsulatedInterfaceType,
data: &[u8],
transport_type: TransportType,
) -> Result<Vec<u8, MAX_ADU_FRAME_LEN>, MbusError> {
let pdu = ReqPduCompiler::encapsulated_interface_transport_request(mei_type, data)?;
common::compile_adu_frame(txn_id, unit_id, pdu, transport_type)
}
pub fn read_exception_status(
unit_id: u8,
transport_type: TransportType,
) -> Result<Vec<u8, MAX_ADU_FRAME_LEN>, MbusError> {
Self::check_serial(&transport_type)?;
let pdu = ReqPduCompiler::read_exception_status_request()?;
common::compile_adu_frame(0, unit_id, pdu, transport_type)
}
pub fn diagnostics(
unit_id: u8,
sub_function: DiagnosticSubFunction,
data: &[u16],
transport_type: TransportType,
) -> Result<Vec<u8, MAX_ADU_FRAME_LEN>, MbusError> {
Self::check_serial(&transport_type)?;
let pdu = ReqPduCompiler::diagnostics_request(sub_function, data)?;
common::compile_adu_frame(0, unit_id, pdu, transport_type)
}
pub fn get_comm_event_counter(
unit_id: u8,
transport_type: TransportType,
) -> Result<Vec<u8, MAX_ADU_FRAME_LEN>, MbusError> {
Self::check_serial(&transport_type)?;
let pdu = ReqPduCompiler::get_comm_event_counter_request()?;
common::compile_adu_frame(0, unit_id, pdu, transport_type)
}
pub fn get_comm_event_log(
unit_id: u8,
transport_type: TransportType,
) -> Result<Vec<u8, MAX_ADU_FRAME_LEN>, MbusError> {
Self::check_serial(&transport_type)?;
let pdu = ReqPduCompiler::get_comm_event_log_request()?;
common::compile_adu_frame(0, unit_id, pdu, transport_type)
}
pub fn report_server_id(
unit_id: u8,
transport_type: TransportType,
) -> Result<Vec<u8, MAX_ADU_FRAME_LEN>, MbusError> {
Self::check_serial(&transport_type)?;
let pdu = ReqPduCompiler::report_server_id_request()?;
common::compile_adu_frame(0, unit_id, pdu, transport_type)
}
fn check_serial(transport_type: &TransportType) -> Result<(), MbusError> {
match transport_type {
TransportType::StdSerial(_) | TransportType::CustomSerial(_) => Ok(()),
_ => Err(MbusError::InvalidTransport), }
}
}