///|
pub struct CanFrame {
id_value : Int
data_value : Bytes
} derive(Eq, Debug)
///|
pub struct DecodedFrame {
frame_value : CanFrame
message_value : DbcMessage
signals_value : Array[DecodedSignal]
} derive(Eq, Debug)
///|
pub fn CanFrame::new(id : Int, data : Bytes) -> Result[CanFrame, DbcError] {
if id < 0 || id > 536870911 {
Err(
DbcError::new(
InvalidMessage,
"CAN frame id is outside the 29-bit range",
1,
1,
),
)
} else if data.length() > 64 {
Err(
DbcError::new(InvalidDataLength, "CAN frame data exceeds 64 bytes", 1, 1),
)
} else {
Ok({
id_value: id,
data_value: Bytes::makei(data.length(), index => data[index]),
})
}
}
///|
pub fn CanFrame::id(self : CanFrame) -> Int {
self.id_value
}
///|
pub fn CanFrame::data(self : CanFrame) -> Bytes {
Bytes::makei(self.data_value.length(), index => self.data_value[index])
}
///|
pub fn DecodedFrame::frame(self : DecodedFrame) -> CanFrame {
self.frame_value
}
///|
pub fn DecodedFrame::message(self : DecodedFrame) -> DbcMessage {
self.message_value
}
///|
pub fn DecodedFrame::signals(self : DecodedFrame) -> Array[DecodedSignal] {
self.signals_value.copy()
}
///|
pub fn DecodedFrame::find_signal(
self : DecodedFrame,
name : String,
) -> DecodedSignal? {
for signal in self.signals_value {
if signal.name() == name {
return Some(signal)
}
}
None
}
///|
fn hex_value(code : Int) -> Int {
if code >= 48 && code <= 57 {
code - 48
} else if code >= 65 && code <= 70 {
code - 55
} else if code >= 97 && code <= 102 {
code - 87
} else {
-1
}
}
///|
fn hex_character(value : Int) -> String {
"0123456789ABCDEF"[value & 15].to_char().unwrap().to_string()
}
///|
pub fn parse_frame_hex(id : Int, text : String) -> Result[CanFrame, DbcError] {
if text.length() % 2 != 0 {
return Err(
DbcError::new(
InvalidDataLength,
"hex frame data must have an even digit count",
1,
1,
),
)
}
if text.length() > 128 {
return Err(
DbcError::new(InvalidDataLength, "hex frame data exceeds 64 bytes", 1, 1),
)
}
for index in 0.. {
let high = hex_value(text[index * 2].to_int())
let low = hex_value(text[index * 2 + 1].to_int())
(high * 16 + low).to_byte()
})
CanFrame::new(id, data)
}
///|
pub fn render_frame_hex(frame : CanFrame) -> String {
let mut output = ""
for byte in frame.data() {
output = output +
hex_character(byte.to_int() >> 4) +
hex_character(byte.to_int())
}
output
}
///|
pub fn decode_frame(
database : DbcDatabase,
frame : CanFrame,
) -> Result[DecodedFrame, DbcError] {
let message = match database.find_message_by_id(frame.id()) {
Some(value) => value
None =>
return Err(
DbcError::new(
UnknownMessage,
"frame id is not defined in the DBC database",
1,
1,
context=frame.id().to_string(),
),
)
}
let signals = match decode_message(message, frame.data()) {
Ok(value) => value
Err(error) => return Err(error)
}
Ok({ frame_value: frame, message_value: message, signals_value: signals })
}
///|
pub fn encode_frame(
database : DbcDatabase,
message_id : Int,
assignments : Array[SignalAssignment],
) -> Result[CanFrame, DbcError] {
let message = match database.find_message_by_id(message_id) {
Some(value) => value
None =>
return Err(
DbcError::new(
UnknownMessage,
"message id is not defined in the DBC database",
1,
1,
context=message_id.to_string(),
),
)
}
let data = match encode_message(message, assignments) {
Ok(value) => value
Err(error) => return Err(error)
}
CanFrame::new(message_id, data)
}
///|
pub fn decode_frame_hex(
database : DbcDatabase,
message_id : Int,
hex_data : String,
) -> Result[DecodedFrame, DbcError] {
let frame = match parse_frame_hex(message_id, hex_data) {
Ok(value) => value
Err(error) => return Err(error)
}
decode_frame(database, frame)
}