use crate::types::{PduCllHandle, PduCopHandle, PduModuleHandle, PduUniqueCopTag};
use dpdu_api_types::{PDU_HANDLE_UNDEF, PduErrorEvt, PduInfo, PduStatus};
use std::fmt::{Display, Formatter};
use std::ops::{Deref, DerefMut};
use std::sync::{Arc, OnceLock};
pub type StopReceive = bool;
#[derive(Debug, Clone)]
pub struct PduEvent {
pub target: PduEventTarget,
pub h_cop: Option<PduCopHandle>,
pub cop_tag: Option<PduUniqueCopTag>,
pub timestamp: u32,
pub data: PduEventData,
}
#[derive(Debug, Clone, strum::AsRefStr, strum::Display)]
pub enum PduEventTarget {
System,
Module(PduModuleHandle),
LogicalLink(PduModuleHandle, PduCllHandle),
}
impl PduEventTarget {
pub(crate) fn from_callback(h_mod: PduModuleHandle, h_cll: PduCllHandle) -> Self {
let h_mod_opt = (h_mod != PDU_HANDLE_UNDEF).then(|| h_mod);
let h_cll_opt = (h_cll != PDU_HANDLE_UNDEF).then(|| h_cll);
match (h_mod_opt, h_cll_opt) {
(None, None) => PduEventTarget::System,
(Some(h_mod), None) => PduEventTarget::Module(h_mod),
(Some(h_mod), Some(h_cll)) => PduEventTarget::LogicalLink(h_mod, h_cll),
_ => {
unreachable!("internal error: CLL handle cannot exist without a module handle");
}
}
}
pub fn is_system(&self) -> bool {
matches!(self, PduEventTarget::System)
}
pub fn is_module(&self) -> bool {
matches!(self, PduEventTarget::Module(..))
}
pub fn is_logical_link(&self) -> bool {
matches!(self, PduEventTarget::LogicalLink(..))
}
pub fn get_module_handle(&self) -> Option<PduModuleHandle> {
match self {
PduEventTarget::Module(h_mod) => Some(h_mod.clone()),
PduEventTarget::LogicalLink(h_mod, ..) => Some(h_mod.clone()),
_ => None,
}
}
pub fn get_cll_handle(&self) -> Option<PduCllHandle> {
match self {
PduEventTarget::LogicalLink(_, h_cll) => Some(h_cll.clone()),
_ => None,
}
}
}
#[derive(Debug, Clone, strum::AsRefStr)]
pub enum PduEventData {
Status(PduStatusEvent),
Result(PduResultEvent),
Error(PduErrorEvent),
Info(PduInfoEvent),
}
impl From<PduStatusEvent> for PduEventData {
fn from(value: PduStatusEvent) -> Self {
PduEventData::Status(value)
}
}
impl From<PduResultEvent> for PduEventData {
fn from(value: PduResultEvent) -> Self {
PduEventData::Result(value)
}
}
impl From<PduErrorEvent> for PduEventData {
fn from(value: PduErrorEvent) -> Self {
PduEventData::Error(value)
}
}
impl From<PduInfoEvent> for PduEventData {
fn from(value: PduInfoEvent) -> Self {
PduEventData::Info(value)
}
}
impl PduEventData {
pub fn as_str(&self) -> &str {
self.as_ref()
}
pub fn as_status(&self) -> Option<&PduStatusEvent> {
match self {
PduEventData::Status(v) => Some(v),
_ => None,
}
}
pub fn as_result(&self) -> Option<&PduResultEvent> {
match self {
PduEventData::Result(v) => Some(v),
_ => None,
}
}
pub fn as_error(&self) -> Option<&PduErrorEvent> {
match self {
PduEventData::Error(v) => Some(v),
_ => None,
}
}
pub fn as_info(&self) -> Option<&PduInfoEvent> {
match self {
PduEventData::Info(v) => Some(v),
_ => None,
}
}
}
#[repr(transparent)]
#[derive(Debug, Clone)]
pub struct PduStatusEvent(pub PduStatus);
impl Deref for PduStatusEvent {
type Target = PduStatus;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for PduStatusEvent {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
#[derive(Debug, Clone)]
pub struct PduResultEvent {
pub rx_flags: PduResultEventRxFlags,
pub unique_resp_identifier: u32,
pub acceptance_id: u32,
pub timestamp_flags: PduResultEventTimestampFlags,
pub tx_msg_done_timestamp: u32,
pub start_msg_timestamp: u32,
pub data: Vec<u8>,
pub extra_info_header: Option<Vec<u8>>,
pub extra_info_footer: Option<Vec<u8>>,
}
#[derive(Debug, Clone)]
pub struct PduResultEventRxFlags(Vec<u8>);
impl From<Vec<u8>> for PduResultEventRxFlags {
fn from(value: Vec<u8>) -> Self {
PduResultEventRxFlags(value)
}
}
impl Deref for PduResultEventRxFlags {
type Target = Vec<u8>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for PduResultEventRxFlags {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl PduResultEventRxFlags {
pub fn is_remote_frame(&self) -> bool {
if let Some(byte) = self.get(0) {
return (*byte & 0x80) != 0;
}
false
}
pub fn is_speed_change_event(&self) -> bool {
if let Some(byte) = self.get(1) {
return (*byte & 0x04) != 0;
}
false
}
pub fn is_ecu_timing_changed(&self) -> bool {
if let Some(byte) = self.get(1) {
return (*byte & 0x02) != 0;
}
false
}
pub fn is_sw_can_high_voltage_msg(&self) -> bool {
if let Some(byte) = self.get(1) {
return (*byte & 0x01) != 0;
}
false
}
pub fn is_can_29_bit_id(&self) -> bool {
if let Some(byte) = self.get(2) {
return (*byte & 0x01) != 0;
}
false
}
pub fn is_can_segmentation(&self) -> bool {
if let Some(byte) = self.get(3) {
return (*byte & 0x40) != 0;
}
false
}
pub fn is_iso_15765_padding_error(&self) -> bool {
if let Some(byte) = self.get(3) {
return (*byte & 0x10) != 0;
}
false
}
pub fn get_tx_status(&self) -> bool {
if let Some(byte) = self.get(3) {
return (*byte & 0x08) != 0;
}
false
}
pub fn get_rx_break_status(&self) -> bool {
if let Some(byte) = self.get(3) {
return (*byte & 0x04) != 0;
}
false
}
pub fn is_start_of_message(&self) -> bool {
if let Some(byte) = self.get(3) {
return (*byte & 0x02) != 0;
}
false
}
pub fn get_tx_msg_type(&self) -> bool {
if let Some(byte) = self.get(3) {
return (*byte & 0x01) != 0;
}
false
}
pub fn is_iso_15765_addr_type(&self) -> bool {
if let Some(byte) = self.get(3) {
return (*byte & 0x80) != 0;
}
false
}
}
#[derive(Debug, Clone)]
pub struct PduResultEventTimestampFlags(Vec<u8>);
impl From<Vec<u8>> for PduResultEventTimestampFlags {
fn from(value: Vec<u8>) -> Self {
PduResultEventTimestampFlags(value)
}
}
impl Deref for PduResultEventTimestampFlags {
type Target = Vec<u8>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for PduResultEventTimestampFlags {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl PduResultEventTimestampFlags {
pub fn is_tx_msg_done_timestamp_indicator(&self) -> bool {
if let Some(byte) = self.get(0) {
return (*byte & 0x80) != 0;
}
false
}
pub fn is_start_msg_timestamp_indicator(&self) -> bool {
if let Some(byte) = self.get(0) {
return (*byte & 0x40) != 0;
}
false
}
}
#[derive(Debug, Clone)]
pub struct PduErrorEvent {
pub code: PduErrorEvt,
pub extra_code: u32,
}
impl Display for PduErrorEvent {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"PduErrorEvent: code={}, extra_code={}",
self.code.as_ref(),
self.extra_code
)
}
}
#[derive(Debug, Clone)]
pub struct PduInfoEvent {
pub code: PduInfo,
pub extra_code: u32,
}
impl Display for PduInfoEvent {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"PduInfoEvent: code={}, extra_code={}",
self.code.as_ref(),
self.extra_code
)
}
}
#[derive(Debug)]
pub struct ErrorEventStore(OnceLock<PduErrorEvent>);
impl ErrorEventStore {
pub(crate) fn new() -> Arc<Self> {
Arc::new(Self(OnceLock::default()))
}
pub(crate) fn set(&self, event: PduErrorEvent) -> Result<(), PduErrorEvent> {
self.0.set(event)
}
pub fn get(&self) -> Option<&PduErrorEvent> {
self.0.get()
}
}