Skip to content

Commit

Permalink
support send CAN packet from user inputs
Browse files Browse the repository at this point in the history
  • Loading branch information
TuEmb committed Sep 19, 2024
1 parent 8e2779a commit 316902a
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 19 deletions.
78 changes: 74 additions & 4 deletions src/event_handler/can_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ impl<'a> CanHandler<'a> {
let _ = can_if.bring_down();
let _ = can_if.set_bitrate(self.bitrate().unwrap(), None);
let _ = can_if.bring_up();
let can_socket = self.open_can_socket();
self.process_ui_events(can_socket, can_if);
let tx_can_socket = self.open_can_socket();
let rx_can_socket = self.open_can_socket();
self.process_ui_events(tx_can_socket, rx_can_socket, can_if);
}
#[cfg(target_os = "windows")]
self.process_ui_events(dbc);
Expand All @@ -63,9 +64,54 @@ impl<'a> CanHandler<'a> {
}
}
#[cfg(target_os = "linux")]
fn process_ui_events(&mut self, can_socket: CanSocket, can_if: CanInterface) {
fn process_ui_events(
&mut self,
tx_can_socket: CanSocket,
rx_can_socket: CanSocket,
can_if: CanInterface,
) {
use socketcan::{ExtendedId, StandardId};

let mut start_bus_load = Instant::now();
let mut total_bits = 0;
let _ = self.ui_handle.upgrade_in_event_loop(move |ui| {
ui.on_can_transmit(move |is_extended, can_id, can_data| {
match Self::convert_hex_string_u32(&can_id) {
Ok(id) => match Self::convert_hex_string_arr(&can_data) {
Ok(data) => {
if is_extended {
match ExtendedId::new(id) {
Some(id) => {
let can_frame = CanFrame::new(id, &data).unwrap();
let _ = tx_can_socket.write_frame(&can_frame);
}
None => {
println!("Invalid CAN extended ID {}", id)
}
}
} else {
match StandardId::new(id as u16) {
Some(id) => {
let can_frame = CanFrame::new(id, &data).unwrap();
let _ = tx_can_socket.write_frame(&can_frame);
}
None => {
println!("Invalid CAN standard ID {}", id)
}
}
};
}
Err(e) => {
println!("Failed to parse can data {}, error {}", can_data, e);
}
},
Err(e) => {
println!("Failed to parse can id {}, error: {}", can_id, e);
}
}
});
});

loop {
let bus_state = match can_if.state().unwrap().unwrap() {
socketcan::nl::CanState::ErrorActive => "ERR_ACTIVE",
Expand Down Expand Up @@ -103,7 +149,7 @@ impl<'a> CanHandler<'a> {
}
}
}
if let Ok(frame) = can_socket.read_frame() {
if let Ok(frame) = rx_can_socket.read_frame() {
let _ = self.can_tx.send(frame);
total_bits += (frame.len() + 6) * 8; // Data length + overhead (approximation)
let frame_id = frame.raw_id() & !0x80000000;
Expand Down Expand Up @@ -293,6 +339,30 @@ impl<'a> CanHandler<'a> {
padded_data
}

fn convert_hex_string_u32(hex_str: &str) -> Result<u32, String> {
// Attempt to parse the hex string as a u32
u32::from_str_radix(hex_str, 16).map_err(|e| format!("Failed to convert to u32: {}", e))
}

fn convert_hex_string_arr(hex_str: &str) -> Result<Vec<u8>, String> {
// Remove any whitespace from the input string
let hex_str = hex_str.trim();

// Ensure the string has an even length
if hex_str.len() % 2 != 0 {
return Err("Hex string must have an even number of characters".to_string());
}

// Convert the string into a vector of u8 bytes
(0..hex_str.len())
.step_by(2)
.map(|i| {
u8::from_str_radix(&hex_str[i..i + 2], 16)
.map_err(|e| format!("Failed to convert to u8: {}", e))
})
.collect()
}

fn array_to_hex_string(data: &[u8]) -> String {
// Preallocate space for efficiency
let mut hex_string = String::with_capacity(data.len() * 3);
Expand Down
1 change: 0 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ async fn main() -> io::Result<()> {
// Handle start event
let ui_handle = ui.as_weak();
ui.on_start(move |_name, _index, bitrate| {
// start_tx.send((_name, _index));
#[cfg(target_os = "linux")]
{
let ui = ui_handle.unwrap();
Expand Down
4 changes: 4 additions & 0 deletions ui/app.slint
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export component AppWindow inherits Window {
callback open_dbc_file();
callback filter_id(CanData, bool);
callback start(string, int, string);
callback can_transmit(bool, string, string);
title: @tr("CAN VIEWER (version 0.2.2)");
icon: @image-url("images/can_viewer_128px.png");
background: #1a1f2b;
Expand Down Expand Up @@ -122,6 +123,9 @@ export component AppWindow inherits Window {
change_state(en) => {
is_debug_en = en;
}
can_transmit(is_extended, can_id, can_data) => {
can_transmit(is_extended, can_id, can_data)
}
}
}
}
Expand Down
31 changes: 17 additions & 14 deletions ui/debug_page.slint
Original file line number Diff line number Diff line change
Expand Up @@ -39,27 +39,21 @@ export component StartPauseButton inherits Rectangle {
}

export component CanTransmitData inherits Rectangle {
callback send(bool, string, string, string);
callback send(bool, string, string);
HorizontalLayout {
is_extended := MyCheckBox {
text: "Extended Frame";
}
can_id := LineEdit {
placeholder-text: "ID (hex)";
input-type: decimal;
}
can_len := LineEdit {
placeholder-text: "length";
input-type: number;
placeholder-text: "ID (hex) - eg: 1814FF12";
}
can_data := LineEdit {
placeholder-text: "data (hex)";
input-type: decimal;
placeholder-text: "data (hex) - eg: 1A2B3C4D";
}
Button {
text: "send";
clicked => {
send(is_extended.checked, can_id.text, can_len.text, can_data.text)
send(is_extended.checked, can_id.text, can_data.text)
}
}
}
Expand All @@ -76,6 +70,7 @@ export component debugPage inherits Rectangle {
{id: "181FF1FA", len: 4, data: "00 01 02 03 04 05 06 07"},
{id: "181FF1FA", len: 4, data: "00 01 02 03 04 05 06 07"}];
callback change_state(bool);
callback can_transmit(bool, string, string);

VerticalLayout {
HorizontalLayout {
Expand Down Expand Up @@ -182,16 +177,24 @@ export component debugPage inherits Rectangle {
}
VerticalLayout {
CanTransmitData {

send(is_extended, can_id, can_data) => {
can_transmit(is_extended, can_id, can_data);
}
}
CanTransmitData {

send(is_extended, can_id, can_data) => {
can_transmit(is_extended, can_id, can_data);
}
}
CanTransmitData {

send(is_extended, can_id, can_data) => {
can_transmit(is_extended, can_id, can_data);
}
}
CanTransmitData {

send(is_extended, can_id, can_data) => {
can_transmit(is_extended, can_id, can_data);
}
}
}
}
Expand Down

0 comments on commit 316902a

Please sign in to comment.