update period send message
This commit is contained in:
parent
cc56f48c0a
commit
fdda601379
@ -10,6 +10,7 @@ edition = "2018"
|
|||||||
gtk = "0.14.1"
|
gtk = "0.14.1"
|
||||||
gio = "0.14.6"
|
gio = "0.14.6"
|
||||||
glib = "0.14.5"
|
glib = "0.14.5"
|
||||||
|
#pretty-hex = "0.2.1"
|
||||||
#gtk4 = {git = "https://github.com/gtk-rs/gtk4-rs/"}
|
#gtk4 = {git = "https://github.com/gtk-rs/gtk4-rs/"}
|
||||||
#gtk4 = "0.3.0"
|
#gtk4 = "0.3.0"
|
||||||
#gio4_sys ="0."
|
#gio4_sys ="0."
|
||||||
|
68
src/hexdump.rs
Normal file
68
src/hexdump.rs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
pub fn get_hex(prefix_len: u32, data: Vec<u8>) -> String {
|
||||||
|
let mut header_begin = prefix_len >> 4;
|
||||||
|
let mut counter = prefix_len % 16;
|
||||||
|
// println!("{}", header_begin);
|
||||||
|
// println!("{}", counter);
|
||||||
|
let mut ret = String::new();
|
||||||
|
|
||||||
|
for i in data {
|
||||||
|
if counter % 16 == 0 {
|
||||||
|
counter = 0;
|
||||||
|
// if header_begin != 0 {
|
||||||
|
// ret.push('\n');
|
||||||
|
// }
|
||||||
|
header_begin += 1;
|
||||||
|
ret += &format!("{:04x}\t", header_begin - 1);
|
||||||
|
}
|
||||||
|
counter += 1;
|
||||||
|
ret = ret + &*format!("{:02x} ", i);
|
||||||
|
if counter % 16 ==0 {
|
||||||
|
ret.push('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_ascii(prefix_len: u32, data: Vec<u8>) -> String {
|
||||||
|
let mut header_begin = prefix_len >> 4;
|
||||||
|
let mut counter = prefix_len % 16;
|
||||||
|
// println!("{}", header_begin);
|
||||||
|
// println!("{}", counter);
|
||||||
|
let mut ret = String::new();
|
||||||
|
|
||||||
|
for i in data {
|
||||||
|
if counter % 16 == 0 {
|
||||||
|
counter = 0;
|
||||||
|
// if header_begin != 0 { ret.push('\n'); }
|
||||||
|
header_begin += 1;
|
||||||
|
ret += &format!("{:04x}\t", header_begin - 1);
|
||||||
|
}
|
||||||
|
counter += 1;
|
||||||
|
|
||||||
|
if i.is_ascii_alphanumeric() || i.is_ascii_punctuation() || i.is_ascii_graphic() {
|
||||||
|
// ret += &*(i as char).to_string();
|
||||||
|
ret.push(char::from(i));
|
||||||
|
// basic_show.push(i as char);
|
||||||
|
} else {
|
||||||
|
ret += ".";
|
||||||
|
}
|
||||||
|
|
||||||
|
if counter % 16 ==0 {
|
||||||
|
ret.push('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::hexdump::get_hex;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn exploration() {
|
||||||
|
let data = vec![10, 20, 203];
|
||||||
|
let tmp = get_hex(14, data);
|
||||||
|
println!("{}", tmp);
|
||||||
|
// assert_eq!(2 + 2, 4);
|
||||||
|
}
|
||||||
|
}
|
158
src/main.rs
158
src/main.rs
@ -1,11 +1,13 @@
|
|||||||
#![windows_subsystem = "windows"]
|
#![windows_subsystem = "windows"]
|
||||||
|
|
||||||
mod port;
|
mod port;
|
||||||
|
mod hexdump;
|
||||||
|
|
||||||
use closure::closure;
|
use closure::closure;
|
||||||
|
|
||||||
use gtk::{Inhibit, TextView, Statusbar, Label};
|
use gtk::{Inhibit, TextView, Statusbar, Label};
|
||||||
use gtk::{gio, glib};
|
use gtk::{gio, glib};
|
||||||
use gtk::prelude::{GtkWindowExt, BuilderExtManual, GtkMenuItemExt, WidgetExt, EntryExt, TextBufferExt};
|
use gtk::prelude::{GtkWindowExt, BuilderExtManual, GtkMenuItemExt, WidgetExt, EntryExt, TextBufferExt, ScrolledWindowExt, AdjustmentExt};
|
||||||
use gio::prelude::{ApplicationExt, ApplicationExtManual};
|
use gio::prelude::{ApplicationExt, ApplicationExtManual};
|
||||||
use std::sync::mpsc::{Sender, Receiver, channel};
|
use std::sync::mpsc::{Sender, Receiver, channel};
|
||||||
use serialport::{StopBits, FlowControl, Parity, DataBits};
|
use serialport::{StopBits, FlowControl, Parity, DataBits};
|
||||||
@ -13,6 +15,10 @@ use crate::port::*;
|
|||||||
use gtk::prelude::TextViewExt;
|
use gtk::prelude::TextViewExt;
|
||||||
use gtk::prelude::LabelExt;
|
use gtk::prelude::LabelExt;
|
||||||
|
|
||||||
|
use std::str;
|
||||||
|
use std::time::Duration;
|
||||||
|
use std::num::ParseIntError;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let application = gtk::Application::new(
|
let application = gtk::Application::new(
|
||||||
Some("com.github.gtk-rs.examples.menu_bar_system"),
|
Some("com.github.gtk-rs.examples.menu_bar_system"),
|
||||||
@ -27,8 +33,8 @@ fn main() {
|
|||||||
|
|
||||||
fn build_ui(application: >k::Application) {
|
fn build_ui(application: >k::Application) {
|
||||||
let builder = gtk::Builder::from_string(include_str!("test.ui"));
|
let builder = gtk::Builder::from_string(include_str!("test.ui"));
|
||||||
let main_window: gtk::ApplicationWindow = builder.object("main_window").expect("Can not get window!");
|
let ui_main_window: gtk::ApplicationWindow = builder.object("main_window").expect("Can not get window!");
|
||||||
main_window.set_application(Some(application));
|
ui_main_window.set_application(Some(application));
|
||||||
let menu_view_command: gtk::MenuItem = builder.object("view_command").expect("Can not get command item");
|
let menu_view_command: gtk::MenuItem = builder.object("view_command").expect("Can not get command item");
|
||||||
let command_entry: gtk::Entry = builder.object("command_entry").expect("Can not get command entry");
|
let command_entry: gtk::Entry = builder.object("command_entry").expect("Can not get command entry");
|
||||||
let tmp = command_entry.clone();
|
let tmp = command_entry.clone();
|
||||||
@ -40,23 +46,38 @@ fn build_ui(application: >k::Application) {
|
|||||||
tmp.set_has_focus(true);
|
tmp.set_has_focus(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let log_window: gtk::Window = builder.object("log_window").expect("Can not get log view");
|
let ui_log_window: gtk::Window = builder.object("log_window").expect("Can not get log view");
|
||||||
let menu_log_command: gtk::MenuItem = builder.object("log_command").expect("Can not get log command");
|
let menu_log_command: gtk::MenuItem = builder.object("log_command").expect("Can not get log command");
|
||||||
|
let menu_hex_command: gtk::MenuItem = builder.object("hex_command").expect("Can not get log command");
|
||||||
let ui_receive_view: TextView = builder.object("receive_view").expect("can not get receive view");
|
let ui_receive_view: TextView = builder.object("receive_view").expect("can not get receive view");
|
||||||
let ui_baudrate: Label = builder.object("ui_baudrate").unwrap();
|
let ui_baudrate: Label = builder.object("ui_baudrate").unwrap();
|
||||||
let ui_databit: Label = builder.object("ui_databit").unwrap();
|
let ui_databit: Label = builder.object("ui_databit").unwrap();
|
||||||
let ui_parity: Label = builder.object("ui_parity").unwrap();
|
let ui_parity: Label = builder.object("ui_parity").unwrap();
|
||||||
let ui_stopbit: Label = builder.object("ui_stopbit").unwrap();
|
let ui_stopbit: Label = builder.object("ui_stopbit").unwrap();
|
||||||
|
let ui_period: Label = builder.object("ui_period").unwrap();
|
||||||
let ui_com: Label = builder.object("ui_com").unwrap();
|
let ui_com: Label = builder.object("ui_com").unwrap();
|
||||||
let ui_statusbar: Statusbar = builder.object("statusbar").unwrap();
|
let ui_statusbar: Statusbar = builder.object("statusbar").unwrap();
|
||||||
let ui_log_view: TextView = builder.object("log_view").unwrap();
|
let ui_log_view: TextView = builder.object("log_view").unwrap();
|
||||||
|
let ui_hex_view: TextView = builder.object("hex_view").unwrap();
|
||||||
|
let ui_hex_window: gtk::Window = builder.object("hex_window").unwrap();
|
||||||
|
let ui_ascii_view: TextView = builder.object("ascii_view").unwrap();
|
||||||
|
let ui_hex_scroll: gtk::ScrolledWindow = builder.object("ui_hex_scroll").unwrap();
|
||||||
|
|
||||||
log_window.show();
|
// ui_viewport.set_vscroll_policy(Sc)
|
||||||
log_window.connect_delete_event(|a, _| {
|
|
||||||
|
|
||||||
|
ui_log_window.show();
|
||||||
|
// ui_hex_window.show();
|
||||||
|
ui_log_window.connect_delete_event(|a, _| {
|
||||||
a.hide();
|
a.hide();
|
||||||
Inhibit(true)
|
Inhibit(true)
|
||||||
});
|
});
|
||||||
let tmp = log_window.clone();
|
|
||||||
|
ui_hex_window.connect_delete_event(|a, _| {
|
||||||
|
a.hide();
|
||||||
|
Inhibit(true)
|
||||||
|
});
|
||||||
|
let tmp = ui_log_window.clone();
|
||||||
menu_log_command.connect_activate(move |_| {
|
menu_log_command.connect_activate(move |_| {
|
||||||
if tmp.is_visible() {
|
if tmp.is_visible() {
|
||||||
tmp.hide();
|
tmp.hide();
|
||||||
@ -64,6 +85,16 @@ fn build_ui(application: >k::Application) {
|
|||||||
tmp.show();
|
tmp.show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let tmp = ui_hex_window.clone();
|
||||||
|
menu_hex_command.connect_activate(move |_| {
|
||||||
|
if tmp.is_visible() {
|
||||||
|
tmp.hide();
|
||||||
|
} else {
|
||||||
|
tmp.show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let mut receive_char_counter = 0;
|
||||||
let (sender_ui_upd, receiver_ui_upd) = glib::MainContext::channel(glib::PRIORITY_DEFAULT);
|
let (sender_ui_upd, receiver_ui_upd) = glib::MainContext::channel(glib::PRIORITY_DEFAULT);
|
||||||
receiver_ui_upd.attach(None, move |msg| {
|
receiver_ui_upd.attach(None, move |msg| {
|
||||||
match msg {
|
match msg {
|
||||||
@ -71,19 +102,41 @@ fn build_ui(application: >k::Application) {
|
|||||||
let buf = ui_log_view.buffer().unwrap();
|
let buf = ui_log_view.buffer().unwrap();
|
||||||
buf.insert(&mut buf.end_iter(), text.as_str());
|
buf.insert(&mut buf.end_iter(), text.as_str());
|
||||||
}
|
}
|
||||||
Message::UiUpdateReceiveMsg(text) => {
|
Message::UiUpdateReceiveMsg(data) => {
|
||||||
|
let mut basic_show = String::new();
|
||||||
|
for i in data.clone() {
|
||||||
|
if i.is_ascii_alphanumeric() || i.is_ascii_whitespace() || i.is_ascii_punctuation() || i.is_ascii_graphic() {
|
||||||
|
basic_show.push(i as char);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let buf = ui_hex_view.buffer().unwrap();
|
||||||
|
let hex = hexdump::get_hex(receive_char_counter, data.clone());
|
||||||
|
buf.insert(&mut buf.end_iter(), hex.as_str());
|
||||||
|
|
||||||
|
// println!("{:?}",std::mem::size_of_val(&buf));
|
||||||
let buf = ui_receive_view.buffer().unwrap();
|
let buf = ui_receive_view.buffer().unwrap();
|
||||||
buf.insert(&mut buf.end_iter(), text.as_str());
|
buf.insert(&mut buf.end_iter(), basic_show.as_str());
|
||||||
ui_receive_view.scroll_to_mark(&buf.get_insert().unwrap(), 0.0, true, 0.5, 0.5);
|
|
||||||
|
|
||||||
|
let buf = ui_ascii_view.buffer().unwrap();
|
||||||
|
let ascii = hexdump::get_ascii(receive_char_counter, data.clone());
|
||||||
|
buf.insert(&mut buf.end_iter(), ascii.as_str());
|
||||||
|
|
||||||
|
receive_char_counter += data.len() as u32;
|
||||||
|
let tmp = ui_hex_scroll.vadjustment();
|
||||||
|
tmp.set_value(tmp.upper());
|
||||||
}
|
}
|
||||||
Message::UiCleanReceiveMsg => ui_receive_view.buffer().unwrap().set_text(""),
|
Message::UiCleanReceiveMsg => ui_receive_view.buffer().unwrap().set_text(""),
|
||||||
Message::UiCleanLog => ui_log_view.buffer().unwrap().set_text(""),
|
Message::UiCleanLog => ui_log_view.buffer().unwrap().set_text(""),
|
||||||
Message::UiShowLog => log_window.show(),
|
Message::UiShowLog => ui_log_window.show(),
|
||||||
Message::UiHideLog => log_window.hide(),
|
Message::UiHideLog => ui_log_window.hide(),
|
||||||
|
Message::UiShowHex => ui_hex_window.show(),
|
||||||
|
Message::UiHideHex => ui_hex_window.hide(),
|
||||||
Message::UiUpdateStatusBarBaudrate(value) => ui_baudrate.set_text(value.to_string().as_str()),
|
Message::UiUpdateStatusBarBaudrate(value) => ui_baudrate.set_text(value.to_string().as_str()),
|
||||||
Message::UiUpdateStatusBarDatabit(value) => ui_databit.set_text(value.to_string().as_str()),
|
Message::UiUpdateStatusBarDatabit(value) => ui_databit.set_text(value.to_string().as_str()),
|
||||||
Message::UiUpdateStatusBarParity(value) => ui_parity.set_text(value.to_string().as_str()),
|
Message::UiUpdateStatusBarParity(value) => ui_parity.set_text(value.to_string().as_str()),
|
||||||
Message::UiUpdateStatusBarStopbit(value) => ui_stopbit.set_text(value.to_string().as_str()),
|
Message::UiUpdateStatusBarStopbit(value) => ui_stopbit.set_text(value.to_string().as_str()),
|
||||||
|
Message::UiUpdateStatusBarPeriod(value) => ui_period.set_text(&*(value.to_string() + " ms")),
|
||||||
Message::UiUpdateStatusBarCom(value) => ui_com.set_text(value.to_string().as_str()),
|
Message::UiUpdateStatusBarCom(value) => ui_com.set_text(value.to_string().as_str()),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
@ -102,7 +155,7 @@ fn build_ui(application: >k::Application) {
|
|||||||
process_cmd(command, to_ui.clone(), gui2main_tx.clone());
|
process_cmd(command, to_ui.clone(), gui2main_tx.clone());
|
||||||
});
|
});
|
||||||
|
|
||||||
main_window.show();
|
ui_main_window.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -135,8 +188,22 @@ fn process_cmd(command: String, to_ui: glib::Sender<Message>, gui2main_tx: Sende
|
|||||||
to_ui.send(Message::UiUpdateLog(list_available_ports().0)).unwrap();
|
to_ui.send(Message::UiUpdateLog(list_available_ports().0)).unwrap();
|
||||||
}
|
}
|
||||||
"send" => {
|
"send" => {
|
||||||
|
if command.len() <= 5 {
|
||||||
|
to_ui.send(Message::UiUpdateLog("no data!\n".parse().unwrap())).unwrap();
|
||||||
|
} else {
|
||||||
gui2main_tx.send(Message::MainCmdSend(command[5..].parse().unwrap())).unwrap();
|
gui2main_tx.send(Message::MainCmdSend(command[5..].parse().unwrap())).unwrap();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
"loop" => {
|
||||||
|
if command.len() <= 5 {
|
||||||
|
to_ui.send(Message::UiUpdateLog("no data!\n".parse().unwrap())).unwrap();
|
||||||
|
} else {
|
||||||
|
gui2main_tx.send(Message::MainCmdSendPeriod(command[5..].parse().unwrap())).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"loopend" => {
|
||||||
|
gui2main_tx.send(Message::MainCmdStopPeriod).unwrap();
|
||||||
|
}
|
||||||
"clean" => {
|
"clean" => {
|
||||||
to_ui.send(Message::UiCleanReceiveMsg).unwrap();
|
to_ui.send(Message::UiCleanReceiveMsg).unwrap();
|
||||||
to_ui.send(Message::UiCleanLog).unwrap();
|
to_ui.send(Message::UiCleanLog).unwrap();
|
||||||
@ -146,7 +213,8 @@ fn process_cmd(command: String, to_ui: glib::Sender<Message>, gui2main_tx: Sende
|
|||||||
to_ui.send(Message::UiUpdateLog("No enough argument\n".to_string())).unwrap();
|
to_ui.send(Message::UiUpdateLog("No enough argument\n".to_string())).unwrap();
|
||||||
} else {
|
} else {
|
||||||
match command_split[1] {
|
match command_split[1] {
|
||||||
"log" => { to_ui.send(Message::UiShowLog).unwrap(); }
|
"log" => to_ui.send(Message::UiShowLog).unwrap(),
|
||||||
|
"hex" => to_ui.send(Message::UiShowHex).unwrap(),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -156,7 +224,8 @@ fn process_cmd(command: String, to_ui: glib::Sender<Message>, gui2main_tx: Sende
|
|||||||
to_ui.send(Message::UiUpdateLog("No enough argument\n".to_string())).unwrap();
|
to_ui.send(Message::UiUpdateLog("No enough argument\n".to_string())).unwrap();
|
||||||
} else {
|
} else {
|
||||||
match command_split[1] {
|
match command_split[1] {
|
||||||
"log" => { to_ui.send(Message::UiHideLog).unwrap(); }
|
"log" => to_ui.send(Message::UiHideLog).unwrap(),
|
||||||
|
"hex" => to_ui.send(Message::UiHideHex).unwrap(),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -168,7 +237,6 @@ fn process_cmd(command: String, to_ui: glib::Sender<Message>, gui2main_tx: Sende
|
|||||||
|
|
||||||
fn main_proc(to_main_tx: Sender<Message>, rx: Receiver<Message>, ui_upd: glib::Sender<Message>) {
|
fn main_proc(to_main_tx: Sender<Message>, rx: Receiver<Message>, ui_upd: glib::Sender<Message>) {
|
||||||
let (mut main2port_tx, _rx_port_receive) = channel::<Message>();
|
let (mut main2port_tx, _rx_port_receive) = channel::<Message>();
|
||||||
let mut default_com_port = "USB0".to_string();
|
|
||||||
let mut port_default_config = PortConfig {
|
let mut port_default_config = PortConfig {
|
||||||
baud_rate: 115_200,
|
baud_rate: 115_200,
|
||||||
data_bits: DataBits::Eight,
|
data_bits: DataBits::Eight,
|
||||||
@ -178,8 +246,8 @@ fn main_proc(to_main_tx: Sender<Message>, rx: Receiver<Message>, ui_upd: glib::S
|
|||||||
timeout: 10,
|
timeout: 10,
|
||||||
};
|
};
|
||||||
let mut port_status_open = false;
|
let mut port_status_open = false;
|
||||||
default_com_port = list_available_ports().1;
|
let mut default_com_port = list_available_ports().1;
|
||||||
ui_upd.send(Message::UiUpdateStatusBarCom(default_com_port.clone()));
|
ui_upd.send(Message::UiUpdateStatusBarCom(default_com_port.clone())).unwrap();
|
||||||
loop {
|
loop {
|
||||||
if let Ok(msg) = rx.try_recv() {
|
if let Ok(msg) = rx.try_recv() {
|
||||||
match msg {
|
match msg {
|
||||||
@ -192,14 +260,14 @@ fn main_proc(to_main_tx: Sender<Message>, rx: Receiver<Message>, ui_upd: glib::S
|
|||||||
let (tmp_to_port, main2port_rx) = channel::<Message>();
|
let (tmp_to_port, main2port_rx) = channel::<Message>();
|
||||||
main2port_tx = tmp_to_port;
|
main2port_tx = tmp_to_port;
|
||||||
|
|
||||||
let port_name = if arg.is_empty() {default_com_port.clone()} else {arg};
|
let port_name = if arg.is_empty() { default_com_port.clone() } else { arg };
|
||||||
default_com_port = port_name.clone();
|
default_com_port = port_name.clone();
|
||||||
ui_upd.send(Message::UiUpdateStatusBarCom(default_com_port.clone()));
|
ui_upd.send(Message::UiUpdateStatusBarCom(default_com_port.clone())).unwrap();
|
||||||
match port_open(port_name, port_default_config) {
|
match port_open(port_name, port_default_config) {
|
||||||
Ok(port) => {
|
Ok(port) => {
|
||||||
port_status_open = true;
|
port_status_open = true;
|
||||||
std::thread::spawn(closure!(clone to_main_tx, || port_proc(port, to_main_tx, main2port_rx)));
|
std::thread::spawn(closure!(clone to_main_tx, || port_proc(port, to_main_tx, main2port_rx)));
|
||||||
ui_upd.send(Message::UiUpdateLog("open Port succeed\n".to_string())).unwrap();
|
ui_upd.send(Message::UiUpdateLog("open port succeed\n".to_string())).unwrap();
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
match e {
|
match e {
|
||||||
@ -211,16 +279,15 @@ fn main_proc(to_main_tx: Sender<Message>, rx: Receiver<Message>, ui_upd: glib::S
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Message::MainCmdClose => {
|
Message::MainCmdClose => {
|
||||||
if port_status_open{
|
if port_status_open {
|
||||||
main2port_tx.send(Message::PortCmdClose).unwrap();
|
main2port_tx.send(Message::PortCmdClose).unwrap();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
ui_upd.send(Message::UiUpdateLog("No port opened\n".to_string())).unwrap();
|
ui_upd.send(Message::UiUpdateLog("No port opened\n".to_string())).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Message::MainCmdSend(msg) => {
|
Message::MainCmdSend(msg) => main2port_tx.send(Message::PortCmdSend(msg)).unwrap(),
|
||||||
main2port_tx.send(Message::PortCmdSend(msg)).unwrap();
|
Message::MainCmdSendPeriod(msg) => { main2port_tx.send(Message::PortPeriodSend(msg)).unwrap() }
|
||||||
}
|
Message::MainCmdStopPeriod=> { main2port_tx.send(Message::PortPeriodStop).unwrap() }
|
||||||
Message::MainCmdSet(args) => {
|
Message::MainCmdSet(args) => {
|
||||||
match args[0].as_str() {
|
match args[0].as_str() {
|
||||||
"baudrate" => {
|
"baudrate" => {
|
||||||
@ -287,7 +354,7 @@ fn main_proc(to_main_tx: Sender<Message>, rx: Receiver<Message>, ui_upd: glib::S
|
|||||||
match value {
|
match value {
|
||||||
1 => port_default_config.stopbit = StopBits::One,
|
1 => port_default_config.stopbit = StopBits::One,
|
||||||
2 => port_default_config.stopbit = StopBits::Two,
|
2 => port_default_config.stopbit = StopBits::Two,
|
||||||
_ => { ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap(); }
|
_ => ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap(),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap();
|
ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap();
|
||||||
@ -306,31 +373,44 @@ fn main_proc(to_main_tx: Sender<Message>, rx: Receiver<Message>, ui_upd: glib::S
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
"period" => {
|
||||||
|
if args.len() != 2 {
|
||||||
|
ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap();
|
||||||
|
} else {
|
||||||
|
match args[1].parse::<u64>() {
|
||||||
|
Ok(value) => {
|
||||||
|
if port_status_open {
|
||||||
|
main2port_tx.send(Message::PortPeriodDuration(value)).unwrap();
|
||||||
|
ui_upd.send(Message::UiUpdateStatusBarPeriod(value)).unwrap();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
ui_upd.send(Message::UiUpdateLog("No port open\n".parse().unwrap())).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => ui_upd.send(Message::UiUpdateLog(format!("{:?}\n", e))).unwrap(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => { ui_upd.send(Message::UiUpdateLog("command does not support!\n".to_string())).unwrap(); }
|
_ => { ui_upd.send(Message::UiUpdateLog("command does not support!\n".to_string())).unwrap(); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Message::PortHaveData(data) => {
|
Message::PortHaveData(data) => {
|
||||||
let mut message_show = String::new();
|
ui_upd.send(Message::UiUpdateReceiveMsg(data)).unwrap();
|
||||||
for i in data {
|
|
||||||
// let char = i as char;
|
|
||||||
// // let char = 'i';
|
|
||||||
if i.is_ascii_alphanumeric() || i.is_ascii_whitespace() || i.is_ascii_punctuation() || i.is_ascii_graphic() {
|
|
||||||
message_show.push(i as char);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ui_upd.send(Message::UiUpdateReceiveMsg(String::from_utf8_lossy(&*data).parse().unwrap())).unwrap();
|
|
||||||
ui_upd.send(Message::UiUpdateReceiveMsg(message_show)).unwrap();
|
|
||||||
}
|
}
|
||||||
Message::PortCloseSucceed => {
|
Message::PortCloseSucceed => {
|
||||||
ui_upd.send(Message::UiUpdateLog("Close port succeed\n".to_string())).unwrap();
|
ui_upd.send(Message::UiUpdateLog("Close port succeed\n".to_string())).unwrap();
|
||||||
port_status_open = false;
|
port_status_open = false;
|
||||||
}
|
}
|
||||||
Message::PortError(msg) => {
|
Message::PortError(msg) => {
|
||||||
ui_upd.send(Message::UiUpdateLog(format!("port closed by error: {}", msg))).unwrap();
|
ui_upd.send(Message::UiUpdateLog(format!("port closed by error: {}\n", msg))).unwrap();
|
||||||
port_status_open = false;
|
port_status_open = false;
|
||||||
}
|
}
|
||||||
|
Message::PortPeriodDuration(value) => {
|
||||||
|
ui_upd.send(Message::UiUpdateStatusBarPeriod(value)).unwrap();
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
std::thread::sleep(Duration::from_millis(20));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
41
src/port.rs
41
src/port.rs
@ -6,26 +6,35 @@ use std::time::Duration;
|
|||||||
|
|
||||||
pub enum Message {
|
pub enum Message {
|
||||||
UiUpdateLog(String),
|
UiUpdateLog(String),
|
||||||
UiUpdateReceiveMsg(String),
|
UiUpdateReceiveMsg(Vec<u8>),
|
||||||
UiCleanReceiveMsg,
|
UiCleanReceiveMsg,
|
||||||
UiCleanLog,
|
UiCleanLog,
|
||||||
UiShowLog,
|
UiShowLog,
|
||||||
UiHideLog,
|
UiHideLog,
|
||||||
|
UiShowHex,
|
||||||
|
UiHideHex,
|
||||||
|
|
||||||
UiUpdateStatusBarCom(String),
|
UiUpdateStatusBarCom(String),
|
||||||
UiUpdateStatusBarBaudrate(u32),
|
UiUpdateStatusBarBaudrate(u32),
|
||||||
UiUpdateStatusBarParity(String),
|
UiUpdateStatusBarParity(String),
|
||||||
UiUpdateStatusBarStopbit(u32),
|
UiUpdateStatusBarStopbit(u32),
|
||||||
|
UiUpdateStatusBarPeriod(u64),
|
||||||
UiUpdateStatusBarDatabit(u32),
|
UiUpdateStatusBarDatabit(u32),
|
||||||
|
|
||||||
MainCmdOpen(String),
|
MainCmdOpen(String),
|
||||||
MainCmdClose,
|
MainCmdClose,
|
||||||
MainCmdSend(String),
|
MainCmdSend(String),
|
||||||
MainCmdSet(Vec<String>),
|
MainCmdSet(Vec<String>),
|
||||||
|
MainCmdSendPeriod(String),
|
||||||
|
MainCmdStopPeriod,
|
||||||
|
|
||||||
PortCmdClose,
|
PortCmdClose,
|
||||||
PortCmdSend(String),
|
PortCmdSend(String),
|
||||||
|
|
||||||
|
PortPeriodSend(String),
|
||||||
|
PortPeriodStop,
|
||||||
|
PortPeriodDuration(u64),
|
||||||
|
|
||||||
PortCloseSucceed,
|
PortCloseSucceed,
|
||||||
PortHaveData(Vec<u8>),
|
PortHaveData(Vec<u8>),
|
||||||
PortError(String),
|
PortError(String),
|
||||||
@ -46,8 +55,8 @@ pub struct PortConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn port_open(port: String, config: PortConfig) -> Result<Box<dyn SerialPort>, Error> {
|
pub fn port_open(port: String, config: PortConfig) -> Result<Box<dyn SerialPort>, Error> {
|
||||||
let mut prelude = ""; if env::consts::OS == "linux" { prelude = "/dev/tty"; }
|
let mut prelude = "";
|
||||||
else if env::consts::OS == "windows" { prelude = "" }
|
if env::consts::OS == "linux" { prelude = "/dev/tty"; } else if env::consts::OS == "windows" { prelude = "" }
|
||||||
let port_builder = serialport::new(prelude.to_owned() + &port, config.baud_rate)
|
let port_builder = serialport::new(prelude.to_owned() + &port, config.baud_rate)
|
||||||
.data_bits(config.data_bits)
|
.data_bits(config.data_bits)
|
||||||
.parity(config.parity)
|
.parity(config.parity)
|
||||||
@ -65,6 +74,11 @@ pub fn port_open(port: String, config: PortConfig) -> Result<Box<dyn SerialPort>
|
|||||||
|
|
||||||
pub fn port_proc(mut port: Box<dyn SerialPort>, to_main: Sender<Message>, from_main: Receiver<Message>) {
|
pub fn port_proc(mut port: Box<dyn SerialPort>, to_main: Sender<Message>, from_main: Receiver<Message>) {
|
||||||
let mut buf: Vec<u8> = vec![0; 128];
|
let mut buf: Vec<u8> = vec![0; 128];
|
||||||
|
let mut period_send = false;
|
||||||
|
let mut period_timeout = std::time::Duration::from_millis(100);
|
||||||
|
let mut period_send_msg = String::new();
|
||||||
|
let mut last_send = std::time::Instant::now();
|
||||||
|
to_main.send(Message::PortPeriodDuration(100));
|
||||||
loop {
|
loop {
|
||||||
if let Ok(msg) = from_main.try_recv() {
|
if let Ok(msg) = from_main.try_recv() {
|
||||||
match msg {
|
match msg {
|
||||||
@ -80,6 +94,16 @@ pub fn port_proc(mut port: Box<dyn SerialPort>, to_main: Sender<Message>, from_m
|
|||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Message::PortPeriodSend(msg) => {
|
||||||
|
period_send = true;
|
||||||
|
period_send_msg = msg;
|
||||||
|
}
|
||||||
|
Message::PortPeriodStop=> {
|
||||||
|
period_send = false;
|
||||||
|
}
|
||||||
|
Message::PortPeriodDuration(value) => {
|
||||||
|
period_timeout = std::time::Duration::from_millis(value);
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -92,10 +116,17 @@ pub fn port_proc(mut port: Box<dyn SerialPort>, to_main: Sender<Message>, from_m
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if period_send && (last_send.elapsed() > period_timeout){
|
||||||
|
last_send = std::time::Instant::now();
|
||||||
|
match port.write(period_send_msg.as_bytes()) {
|
||||||
|
Err(e) => to_main.send(Message::PortError(format!("{}", e).to_string())).unwrap(),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn list_available_ports() -> (String, String){
|
pub(crate) fn list_available_ports() -> (String, String) {
|
||||||
let mut ret = String::new();
|
let mut ret = String::new();
|
||||||
let mut ret_portname = String::new();
|
let mut ret_portname = String::new();
|
||||||
match serialport::available_ports() {
|
match serialport::available_ports() {
|
||||||
@ -111,5 +142,5 @@ pub(crate) fn list_available_ports() -> (String, String){
|
|||||||
ret = format!("{}", err);
|
ret = format!("{}", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(ret,ret_portname)
|
(ret, ret_portname)
|
||||||
}
|
}
|
||||||
|
72
src/test.ui
72
src/test.ui
@ -2,8 +2,60 @@
|
|||||||
<!-- Generated with glade 3.38.2 -->
|
<!-- Generated with glade 3.38.2 -->
|
||||||
<interface>
|
<interface>
|
||||||
<requires lib="gtk+" version="3.24"/>
|
<requires lib="gtk+" version="3.24"/>
|
||||||
|
<object class="GtkWindow" id="hex_window">
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="default-width">900</property>
|
||||||
|
<property name="default-height">400</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkScrolledWindow" id="ui_hex_scroll">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="shadow-type">in</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkViewport">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="shadow-type">out</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkPaned">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTextView" id="hex_view">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="editable">False</property>
|
||||||
|
<property name="monospace">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="resize">False</property>
|
||||||
|
<property name="shrink">True</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTextView" id="ascii_view">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="editable">False</property>
|
||||||
|
<property name="monospace">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="resize">True</property>
|
||||||
|
<property name="shrink">True</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
<object class="GtkWindow" id="log_window">
|
<object class="GtkWindow" id="log_window">
|
||||||
<property name="can-focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
|
<property name="default-width">300</property>
|
||||||
|
<property name="default-height">400</property>
|
||||||
<property name="icon-name">network-server</property>
|
<property name="icon-name">network-server</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkScrolledWindow">
|
<object class="GtkScrolledWindow">
|
||||||
@ -22,8 +74,8 @@
|
|||||||
</object>
|
</object>
|
||||||
<object class="GtkApplicationWindow" id="main_window">
|
<object class="GtkApplicationWindow" id="main_window">
|
||||||
<property name="can-focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="default-width">300</property>
|
<property name="default-width">600</property>
|
||||||
<property name="default-height">400</property>
|
<property name="default-height">800</property>
|
||||||
<property name="icon-name">network-server</property>
|
<property name="icon-name">network-server</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
@ -176,7 +228,7 @@
|
|||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem">
|
<object class="GtkMenuItem" id="hex_command">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can-focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="label" translatable="yes">hex</property>
|
<property name="label" translatable="yes">hex</property>
|
||||||
@ -238,6 +290,7 @@
|
|||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can-focus">True</property>
|
<property name="can-focus">True</property>
|
||||||
<property name="editable">False</property>
|
<property name="editable">False</property>
|
||||||
|
<property name="monospace">True</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
@ -318,6 +371,19 @@
|
|||||||
<property name="position">5</property>
|
<property name="position">5</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="ui_period">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<property name="label" translatable="yes">100 ms</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">6</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user