Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

commonise Windows and Linux code #7

Merged
merged 3 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ winapi = { version = "0.3.9", features = ["winuser"] }
pcan-basic = { git = "https://github.com/TuEmb/pcan-basic.git", branch="main"}

[target.'cfg(unix)'.dependencies]
privilege-rs = "0.1.0"
privilege-rs = "0.1.2"
socketcan = { git = "https://github.com/socketcan-rs/socketcan-rs.git", rev="e0d7760eca8085b247f37ea22f0aa41e00fa25fa", features = ["enumerate"] }

[build-dependencies]
Expand Down
106 changes: 106 additions & 0 deletions src/event_handler/init.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
use crate::slint_generatedAppWindow::{socket_info, AppWindow};
#[cfg(target_os = "windows")]
use pcan_basic::hw::attached_channels as available_interfaces;
use slint::{ComponentHandle, ModelRc, SharedString, VecModel, Weak};
#[cfg(target_os = "linux")]
use socketcan::available_interfaces;
use std::{process::exit, time::Duration};
pub struct Init<'a> {
pub ui_handle: &'a Weak<AppWindow>,
}

impl<'a> Init<'a> {
pub fn run(&self) {
let mut previous_interfaces = Vec::default();
loop {
match available_interfaces() {
Ok(interface) => {
if interface.is_empty() {
let _ = self.ui_handle.upgrade_in_event_loop(move |ui| {
let socket_info = socket_info {
index: ModelRc::new(VecModel::from(Vec::default())),
name: ModelRc::new(VecModel::from(Vec::default())),
};
ui.set_can_sockets(socket_info);
ui.set_init_string(SharedString::from("No CAN device found !"));
});
} else {
#[cfg(target_os = "linux")]
if previous_interfaces != interface {
let interface_clone = interface.clone();
previous_interfaces = interface.clone();
let _ = self.ui_handle.upgrade_in_event_loop(move |ui| {
ui.set_init_string(SharedString::from(format!(
"Found {} CAN devices\n Please select your device ",
interface.len()
)));
});

let _ = self.ui_handle.upgrade_in_event_loop(move |ui| {
let convert_shared_string: Vec<SharedString> = interface_clone
.into_iter()
.map(SharedString::from)
.collect();
let socket_info = socket_info {
index: ModelRc::new(VecModel::from(Vec::default())),
name: ModelRc::new(VecModel::from(convert_shared_string)),
};
ui.set_can_sockets(socket_info);
});
}
#[cfg(target_os = "windows")]
{
let mut interface_names = Vec::default();
let mut interface_index = Vec::default();
let mut count = 0;
for channel in interface {
let interface_name = SharedString::from(format!(
"{}(0x{:02X})",
channel.device_name(),
channel.channel_information.device_id
));
interface_names.push(interface_name);
interface_index
.push(channel.channel_information.channel_handle as i32);
count += 1;
}
if previous_interfaces != interface_names {
previous_interfaces = interface_names.clone();
let _ = self.ui_handle.upgrade_in_event_loop(move |ui| {
ui.set_init_string(SharedString::from(format!(
"Found {} CAN devices\n Please select your device ",
count
)));
let socket_info = socket_info {
index: ModelRc::new(VecModel::from(interface_index)),
name: ModelRc::new(VecModel::from(interface_names)),
};
ui.set_can_sockets(socket_info);
});
}
}
}
}
Err(e) => {
let _ = self.ui_handle.upgrade_in_event_loop(move |ui| {
ui.set_init_string(SharedString::from(format!(
"Can't get device list: {:?}",
e
)));
let socket_info = socket_info {
index: ModelRc::new(VecModel::from(Vec::default())),
name: ModelRc::new(VecModel::from(Vec::default())),
};
ui.set_can_sockets(socket_info);
});
}
};
let _ = self.ui_handle.upgrade_in_event_loop(move |ui| {
if !ui.window().is_visible() {
exit(1);
}
});
std::thread::sleep(Duration::from_micros(50));
}
}
}
2 changes: 2 additions & 0 deletions src/event_handler/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
pub(crate) mod can_handler;
pub(crate) mod dbc_file;
pub(crate) mod init;
pub(crate) mod packet_filter;

pub use can_handler::CanHandler;
pub use dbc_file::DBCFile;
pub use init::Init;
pub use packet_filter::PacketFilter;
#[cfg(target_os = "windows")]
use pcan_basic::socket::Baudrate;
Expand Down
135 changes: 8 additions & 127 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
use std::io;
use std::process::exit;
use std::sync::mpsc;
use std::sync::{Arc, Mutex};
use std::time::Duration;

mod event_handler;
use can_dbc::DBC;
use event_handler::{CanHandler, DBCFile, Init, PacketFilter};
#[cfg(target_os = "windows")]
use event_handler::p_can_bitrate;
use event_handler::{CanHandler, DBCFile, PacketFilter};
#[cfg(target_os = "windows")]
use pcan_basic::{bus::UsbBus, hw::attached_channels, socket::usb::UsbCanSocket};
use pcan_basic::{bus::UsbBus, socket::usb::UsbCanSocket};
#[cfg(target_os = "linux")]
use privilege_rs::privilege_request;
#[cfg(target_os = "windows")]
use slint::Model;
use slint::{ModelRc, SharedString, VecModel};
#[cfg(target_os = "linux")]
use socketcan::available_interfaces;
use slint::SharedString;
#[cfg(target_os = "windows")]
use winapi::um::wincon::FreeConsole;

Expand All @@ -39,125 +33,11 @@ async fn main() -> io::Result<()> {

// Find available socket CAN
let ui_handle = ui.as_weak();
#[cfg(target_os = "linux")]
tokio::spawn(async move {
let mut previous_interfaces = Vec::default();
loop {
match available_interfaces() {
Ok(interface) => {
if interface.is_empty() {
let _ = ui_handle.upgrade_in_event_loop(move |ui| {
let socket_info = socket_info {
index: ModelRc::new(VecModel::from(Vec::default())),
name: ModelRc::new(VecModel::from(Vec::default())),
};
ui.set_can_sockets(socket_info);
ui.set_init_string(SharedString::from("No CAN device found !"));
});
} else if previous_interfaces != interface {
let interface_clone = interface.clone();
previous_interfaces = interface.clone();
let _ = ui_handle.upgrade_in_event_loop(move |ui| {
ui.set_init_string(SharedString::from(format!(
"Found {} CAN devices\n Please select your device ",
interface.len()
)));
});

let _ = ui_handle.upgrade_in_event_loop(move |ui| {
let convert_shared_string: Vec<SharedString> = interface_clone
.into_iter()
.map(SharedString::from)
.collect();
let socket_info = socket_info {
index: ModelRc::new(VecModel::from(Vec::default())),
name: ModelRc::new(VecModel::from(convert_shared_string)),
};
ui.set_can_sockets(socket_info);
});
}
}
Err(e) => {
let _ = ui_handle.upgrade_in_event_loop(move |ui| {
ui.set_init_string(SharedString::from(format!(
"Can't get device list: {}",
e
)));
let socket_info = socket_info {
index: ModelRc::new(VecModel::from(Vec::default())),
name: ModelRc::new(VecModel::from(Vec::default())),
};
ui.set_can_sockets(socket_info);
});
}
};
let _ = ui_handle.upgrade_in_event_loop(move |ui| {
if !ui.window().is_visible() {
exit(1);
}
});
tokio::time::sleep(Duration::from_micros(50)).await;
}
});

#[cfg(target_os = "windows")]
tokio::spawn(async move {
let mut previous_sockets = Vec::default();
loop {
// get channel_handle
match attached_channels() {
Ok(channels) => {
if channels.is_empty() {
let _ = ui_handle.upgrade_in_event_loop(move |ui| {
ui.set_init_string(SharedString::from("No CAN device found !"));
});
} else {
let mut can_socket_names = Vec::default();
let mut can_socket_index = Vec::default();
let mut count = 0;
for channel in channels {
let socket_name = SharedString::from(format!(
"{}(0x{:02X})",
channel.device_name(),
channel.channel_information.device_id
));
can_socket_names.push(socket_name);
can_socket_index
.push(channel.channel_information.channel_handle as i32);
count += 1;
}
if previous_sockets != can_socket_names {
previous_sockets = can_socket_names.clone();
let _ = ui_handle.upgrade_in_event_loop(move |ui| {
ui.set_init_string(SharedString::from(format!(
"Found {} CAN devices\n Please select your device ",
count
)));
let socket_info = socket_info {
index: ModelRc::new(VecModel::from(can_socket_index)),
name: ModelRc::new(VecModel::from(can_socket_names)),
};
ui.set_can_sockets(socket_info);
});
}
}
}
Err(e) => {
let _ = ui_handle.upgrade_in_event_loop(move |ui| {
ui.set_init_string(SharedString::from(format!(
"Can't get device list: {:?}",
e
)));
});
}
}
let _ = ui_handle.upgrade_in_event_loop(move |ui| {
if !ui.window().is_visible() {
exit(1);
}
});
tokio::time::sleep(Duration::from_micros(50)).await;
}
let init_event = Init {
ui_handle: &ui_handle,
};
init_event.run();
});

let (start_tx, start_rx) = mpsc::channel();
Expand All @@ -177,6 +57,7 @@ async fn main() -> io::Result<()> {
}
#[cfg(target_os = "windows")]
{
use event_handler::p_can_bitrate;
let ui = ui_handle.unwrap();
let get_device_handle = match ui.get_can_sockets().index.row_data(_index as usize) {
Some(device) => device,
Expand Down
2 changes: 1 addition & 1 deletion ui/app.slint
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export component AppWindow inherits Window {
callback open_dbc_file();
callback filter_id(CanData, bool);
callback start(string, int, string);
title: @tr("CAN VIEWER (version 0.2.0)");
title: @tr("CAN VIEWER (version 0.2.2)");
icon: @image-url("images/can_viewer_128px.png");
background: #1a1f2b;
default-font-family: "Noto Sans";
Expand Down