adlt/plugins/
anonymize.rsuse crate::{
dlt::{
DltChar4, DltMessage, DLT_SCOD_UTF8, DLT_TYPE_INFO_STRG, SERVICE_ID_GET_LOG_INFO,
SERVICE_ID_GET_SOFTWARE_VERSION,
},
plugins::plugin::{Plugin, PluginState},
};
use std::{
collections::HashMap,
str::FromStr,
sync::{Arc, RwLock},
};
#[derive(Debug)]
pub struct ApidData {
apid: DltChar4,
ctid_map: HashMap<DltChar4, DltChar4>,
}
#[derive(Debug)]
pub struct EcuData {
ecu: DltChar4,
}
#[derive(Debug)]
pub struct AnonymizePlugin {
name: String,
enabled: bool,
state: Arc<RwLock<PluginState>>,
ecu_map: HashMap<DltChar4, EcuData>,
apid_maps: HashMap<DltChar4, HashMap<DltChar4, ApidData>>, }
impl AnonymizePlugin {
pub fn new(name: &str) -> AnonymizePlugin {
AnonymizePlugin {
name: name.to_owned(),
enabled: true,
state: Arc::new(RwLock::new(PluginState::default())),
ecu_map: HashMap::new(),
apid_maps: HashMap::new(),
}
}
fn ecu_anon(&mut self, msg: &mut DltMessage) {
if self.ecu_map.contains_key(&msg.ecu) {
msg.ecu = self.ecu_map.get(&msg.ecu).unwrap().ecu.to_owned();
} else {
let new_ecu = DltChar4::from_str(format!("E{:03}", self.ecu_map.len() + 1).as_str())
.unwrap_or_else(|_| DltChar4::from_buf(b"E99A"));
self.ecu_map.insert(msg.ecu, EcuData { ecu: new_ecu });
msg.ecu = new_ecu;
}
}
fn apid_ctid_anon(&mut self, msg: &mut DltMessage) {
if let Some(cur_apid) = msg.apid() {
let apid_map = self.apid_maps.entry(msg.ecu).or_default();
if !apid_map.contains_key(cur_apid) {
let new_apid = DltChar4::from_str(format!("A{:03}", apid_map.len() + 1).as_str())
.unwrap_or_else(|_| DltChar4::from_buf(b"A99A"));
apid_map.insert(
*cur_apid,
ApidData {
apid: new_apid,
ctid_map: HashMap::new(),
},
);
};
let apid_data = apid_map.get_mut(cur_apid).unwrap(); let cur_ctid = msg.ctid().unwrap();
let new_ctid = if apid_data.ctid_map.contains_key(cur_ctid) {
*apid_data.ctid_map.get(cur_ctid).unwrap()
} else {
let new_ctid =
DltChar4::from_str(format!("C{:03}", apid_data.ctid_map.len() + 1).as_str())
.unwrap_or_else(|_| DltChar4::from_buf(b"C99A"));
apid_data.ctid_map.insert(*cur_ctid, new_ctid);
new_ctid
};
if let Some(extended_header) = msg.extended_header.as_mut() {
extended_header.apid = apid_data.apid;
extended_header.ctid = new_ctid;
}
}
}
fn ctrl_msgs_anon(&mut self, msg: &mut DltMessage) {
if msg.is_ctrl_response() {
let mut args = msg.into_iter();
let message_id_arg = args.next();
let message_id = match message_id_arg {
Some(a) => {
if a.is_big_endian {
u32::from_be_bytes(a.payload_raw.get(0..4).unwrap().try_into().unwrap())
} else {
u32::from_le_bytes(a.payload_raw.get(0..4).unwrap().try_into().unwrap())
}
}
None => 0,
};
match message_id {
SERVICE_ID_GET_SOFTWARE_VERSION => {
let sw_version = "adlt --anon removed sw_version";
let payload = vec![
crate::to_endian_vec!(message_id, msg.is_big_endian()),
vec![0u8], crate::to_endian_vec!(sw_version.len() as u32, msg.is_big_endian()),
sw_version.as_bytes().to_vec(),
];
msg.payload = payload.into_iter().flatten().collect::<Vec<u8>>();
}
SERVICE_ID_GET_LOG_INFO => {
msg.payload = crate::to_endian_vec!(message_id, msg.is_big_endian());
}
_ => {} }
}
}
fn payload_anon(&mut self, msg: &mut DltMessage) {
if !msg.is_ctrl_request() && !msg.is_ctrl_response() {
if !msg.is_verbose() {
if msg.payload.len() >= 4 {
msg.payload = msg.payload[0..4].to_owned();
}
} else {
let sample_payload = "--anon";
let payload = vec![
crate::to_endian_vec!(
(DLT_TYPE_INFO_STRG | DLT_SCOD_UTF8),
msg.is_big_endian()
),
crate::to_endian_vec!((sample_payload.len() + 1) as u16, msg.is_big_endian()),
sample_payload.as_bytes().to_vec(),
vec![0u8], ];
msg.payload = payload.into_iter().flatten().collect::<Vec<u8>>();
}
}
}
}
impl Plugin for AnonymizePlugin {
fn name(&self) -> &str {
&self.name
}
fn enabled(&self) -> bool {
self.enabled
}
fn state(&self) -> Arc<RwLock<PluginState>> {
self.state.clone()
}
fn process_msg(&mut self, msg: &mut DltMessage) -> bool {
if !self.enabled {
return true;
}
self.ecu_anon(msg);
self.apid_ctid_anon(msg);
self.ctrl_msgs_anon(msg);
self.payload_anon(msg);
true
}
}
#[cfg(test)]
mod tests {
#[test]
fn basic() {
}
}