I turned on my brain and managed to make something that actually performs and uses threads properly

This commit is contained in:
Kyan Wanschers 2024-03-05 00:22:04 +01:00
parent 90fadb57e3
commit 66524a39c2
8 changed files with 117 additions and 768 deletions

2
.gitignore vendored
View file

@ -11,4 +11,4 @@ Cargo.lock
**/*.rs.bk
# MSVC Windows builds of rustc generate these, which store debugging information
*.pdbwa
*.pdb

View file

@ -1,8 +1,7 @@
[package]
name = "Wabri"
name = "wabri"
version = "0.1.0"
edition = "2021"
[dependencies]
serialport = "4.3.0"
tokio = { version = "1.36.0", features=["full"] }
serial2 = "0.2.20"

View file

@ -1,18 +0,0 @@
#![feature(exclusive_range_pattern)]
use crate::wacca::CommandPacket;
mod wacca;
fn main() {
let packet = CommandPacket {
out: true,
wedge_id: 6,
command_id: 0x90,
data: vec![0x14, 0x07, 0x7F, 0x3F, 0x44],
};
let b = packet.serialize();
println!("{:X?}",b);
let test: CommandPacket = wacca::CommandPacket::new(wacca::CommandPacket::new(vec![0xD1, 0xA8, 0x31, 0x39, 0x30, 0x35, 0x31, 0x34, 0x30, 0x37, 0x33, 0x34, 0x30, 0x41, 0xF0]).unwrap().serialize()).unwrap();
println!("{:?}",test);
}

View file

@ -1,141 +0,0 @@
#![feature(exclusive_range_pattern)]
use std::io::{self, Write};
use std::sync::{Arc, Mutex};
use std::time::{Duration, Instant};
use std::thread;
use wacca::TouchLink;
pub mod wacca;
#[tokio::main]
async fn main() {
let mut gleft = serialport::new("/dev/tnt0", 115_200)
.timeout(Duration::from_millis(10))
.open()
.expect("Failed to open serial port");
let mut gright = serialport::new("/dev/tnt2", 115_200)
.timeout(Duration::from_millis(10))
.open()
.expect("Failed to open serial port");
let mut wleft = serialport::new("/dev/ttyUSB0", 921_600)
.timeout(Duration::from_millis(10))
.open()
.expect("Failed to open serial port");
let mut wright = serialport::new("/dev/ttyUSB1", 921_600)
.timeout(Duration::from_millis(10))
.open()
.expect("Failed to open serial port");
let mut left: TouchLink<'_> = TouchLink {
scan_active: false,
port: Arc::new(Mutex::new(gleft)),
sync_board_version: "190523",
buffer: vec![0; 1000],
buffer2: vec![0; 1000],
syncboardparams: wacca::SyncBoardParams::get(),
side: false,
touchbuffer: Arc::new(Mutex::new(vec![0; 36])),
wport: Arc::new(Mutex::new(wleft)),
time: Instant::now(),
pollrate: Duration::from_millis(1),
};
let mut right = TouchLink {
scan_active: false,
port: Arc::new(Mutex::new(gright)),
sync_board_version: "190523",
buffer: vec![0; 1000],
buffer2: vec![0; 1000],
syncboardparams: wacca::SyncBoardParams::get(),
side: true,
touchbuffer: Arc::new(Mutex::new(vec![0; 36])),
wport: Arc::new(Mutex::new(wright)),
time: Instant::now(),
pollrate: Duration::from_millis(1),
};
let mut lefttiming2: Instant = Instant::now();
let mut righttiming: Instant = Instant::now();
let mut righttiming2: Instant = Instant::now();
let ltouch = &left.touchbuffer;
let ltouch2 = &left.touchbuffer;
let lwport = &left.wport;
let lport = &left.port;
let rtouch = &right.touchbuffer;
let rtouch2 = &right.touchbuffer;
let rwport = &right.wport;
let rport = &right.port;
tokio::spawn(async move {
let mut timing: Instant = Instant::now();
let ltoucha = ltouch.clone();
loop {
if timing.elapsed() >= Duration::from_millis(8) {
timing = Instant::now();
if left.scan_active {
//wacca::touch_recv(lwport.clone(), ltouch.clone(), false)
}
}
}
});
tokio::spawn(async move {
let mut timing: Instant = Instant::now();
loop {
if timing.elapsed() >= Duration::from_millis(8) {
timing = Instant::now();
if left.scan_active {
//wacca::touch_recv(lwport.clone(), ltouch.clone(), false)
}
}
}
});
tokio::spawn(async move {
loop {
if righttiming.elapsed() >= Duration::from_millis(8) {
if left.scan_active {
}
}
}
});
tokio::spawn(async move {
loop {
if righttiming2.elapsed() >= Duration::from_millis(8) {
if right.scan_active {
}
}
}
});
/* if left.scan_active {
if lefttiming.elapsed() >= Duration::from_millis(8) {
lefttiming = Instant::now();
tokio::spawn(async {wacca::touch_recv(lwport, ltouch, false)});
tokio::spawn(async {wacca::touch_send(lport, ltouch2)});
}
} else {
left.poll();
}
if right.scan_active {
if righttiming.elapsed() >= Duration::from_millis(8) {
righttiming = Instant::now();
tokio::spawn(async {wacca::touch_recv(rwport, rtouch, true)});
tokio::spawn(async {wacca::touch_send(rport, rtouch2)});
}
} else {
right.poll();
*/ //}
}

View file

@ -1,182 +1,91 @@
#![feature(exclusive_range_pattern)]
use std::{io, sync::{atomic::{AtomicBool, Ordering}, mpsc::{self, Receiver, Sender}, Arc}, thread, time::Duration};
use std::io::{self, Write};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{mpsc, Arc, Mutex};
use std::time::{Duration, Instant};
use std::thread;
use serialport::SerialPort;
use wacca::{handle_data, SyncBoardParams, TouchLink};
use serial2::SerialPort;
use wacca::{calc_checksum, SyncBoardParams, TouchBinding};
pub mod wacca;
mod wacca;
#[tokio::main]
async fn main() {
fn main() {
let game_left = Arc::new(SerialPort::open("/dev/tnt0", 115200).expect("Unable to open serialport"));
struct touch<'a> {
wedge: Arc<Mutex<Box<dyn SerialPort>>>,
game: Arc<Mutex<Box<dyn SerialPort>>>,
sync_board_params: SyncBoardParams<'a>,
}
let mut gleft = Arc::new(Mutex::new(serialport::new("/dev/tnt0", 115_200)
.timeout(Duration::from_millis(10))
.open()
.expect("Failed to open serial port")));
let game_right = Arc::new(SerialPort::open("/dev/tnt2", 115200).expect("Unable to open serialport"));
let mut gright = Arc::new(Mutex::new(serialport::new("/dev/tnt2", 115_200)
.timeout(Duration::from_millis(10))
.open()
.expect("Failed to open serial port")));
let bindings = vec![
TouchBinding {
game_serial: game_left,
side: false,
},
TouchBinding {
game_serial: game_right,
side: true,
}
];
let mut wleft = Arc::new(Mutex::new(serialport::new("/dev/ttyUSB0", 921_600)
.timeout(Duration::from_millis(10))
.open()
.expect("Failed to open serial port")));
for binding in bindings.into_iter() {
println!("loading thread");
//let we need some params
let params = SyncBoardParams::get(&binding.side);
//Sync board -> Game writer thread logic
let (writer_tx, writer_rx): (Sender<Vec<u8>>, Receiver<Vec<u8>>) = mpsc::channel();
let command_tx = writer_tx.clone();
let mut wright = Arc::new(Mutex::new(serialport::new("/dev/ttyUSB1", 921_600)
.timeout(Duration::from_millis(10))
.open()
.expect("Failed to open serial port")));
let touchpairs = vec![touch {wedge: wleft, game: gleft, sync_board_params: SyncBoardParams::get(false)}, touch {wedge: wright.clone(), game: gright, sync_board_params: SyncBoardParams::get(true)}];
// let ltouch = &left.touchbuffer;
// let ltouch2 = &left.touchbuffer;
// let lwport = &left.wport;
// let lport = &left.port;
for i in touchpairs.into_iter() {
let gleft = i.game;
let wleft = i.wedge;
let leftparams: SyncBoardParams<'_> = i.sync_board_params;
let lefttouchbuffer = Arc::new(Mutex::new(vec![0; 36]));
let lefttouchactive = Arc::new(AtomicBool::new(false));
let leftactive1 = lefttouchactive.clone();
let leftactive2 = lefttouchactive.clone();
let leftactive3 = lefttouchactive.clone();
// let rtouch = &right.touchbuffer;
// let rtouch2 = &right.touchbuffer;
// let rwport = &right.wport;
// let rport = &right.port;
let righttouchbuffer = Arc::new(Mutex::new(vec![0; 36]));
let righttouchactive: Arc<Mutex<bool>> = Arc::new(Mutex::new(false));
let lefttouchbuffer1: Arc<Mutex<Vec<u8>>> = lefttouchbuffer.clone();
let lport1: Arc<Mutex<Box<dyn SerialPort>>> = gleft.clone();
let lport2: Arc<Mutex<Box<dyn SerialPort>>> = wleft.clone();
let (tx, mut rx) = mpsc::channel();
tokio::spawn(async move {
let ltouch = &lefttouchbuffer;
let lport = wleft;
let mut timing: Instant = Instant::now();
let game_serial_1 = binding.game_serial.clone();
thread::spawn(move || {
loop {
if timing.elapsed() >= Duration::from_millis(8) {
if leftactive2.load(Ordering::Relaxed) {
let touchbuffer: Arc<Mutex<Vec<u8>>> = ltouch.clone();
let port: Arc<Mutex<Box<dyn SerialPort>>> = lport.clone();
timing = Instant::now();
//println!("bib {:?}",);
let _ = tx.send(wacca::touch_recv(port, leftparams.side));
}
} else {thread::sleep(Duration::from_millis(1))}
match writer_rx.recv() {
Ok(data) => {
let _ = SerialPort::write(&game_serial_1,&data);
},
Err(e) => {println!("{:?}",e)}
};
}
});
//AtomicBool to check if touch should be active
let touch_active = Arc::new(AtomicBool::new(false));
//command handler for handshake between game and sync board
let touch_active_2 = touch_active.clone();
let game_serial_2 = binding.game_serial.clone();
tokio::spawn(async move {
let ltouch = &lefttouchbuffer1;
let lport = gleft;
let mut touchbuffer: Vec<u8> = vec![0; 36];
let mut timing: Instant = Instant::now();
thread::spawn(move || {
let mut serialbuffer: Vec<u8> = vec![0; 1000];
loop {
if timing.elapsed() >= Duration::from_millis(8) {
if leftactive1.load(Ordering::Relaxed) {
let port: Arc<Mutex<Box<dyn SerialPort>>> = lport.clone();
timing = Instant::now();
match rx.try_recv() {
Ok(d) => {
for b in 0..d.len() {
touchbuffer[b+1] = d[b];
}
},
Err(err) => {},
};
wacca::touch_send(port, &mut touchbuffer);
let data = loop {
match SerialPort::read(&game_serial_2, serialbuffer.as_mut_slice()) {
Ok(t) => {break serialbuffer[..t].to_vec()},
Err(ref e) if e.kind() == io::ErrorKind::TimedOut => (),
Err(e) => eprintln!("{:?}", e),
}
} else {thread::sleep(Duration::from_millis(1))}
}
};
match wacca::handle_data(&data, &params, touch_active_2.clone()) {
Some(d) => command_tx.send(d).expect("Something has gone wrong!"),
None => (),
};
};
});
tokio::spawn(async move {
let port1 = &lport1;
let port2 = &lport2;
let leftactive3 = &lefttouchactive;
let mut serialbuffer = vec![0; 1000];
let mut timing: Instant = Instant::now();
//Send touch packet
let touch_active_1 = touch_active.clone();
thread::spawn(move || {
loop {
if timing.elapsed() >= Duration::from_millis(100) {
if !leftactive3.load(Ordering::Relaxed) {
timing = Instant::now();
let binding1 = port1.clone();
let mut port = binding1.lock().unwrap();
let binding2 = port2.clone();
let mut port2 = binding2.lock().unwrap();
let mut leftactive3 = leftactive3.clone();
match port.read(serialbuffer.as_mut_slice()) {
Ok(t) => handle_data(&serialbuffer[..t].to_vec(), port, port2, &leftparams, leftactive3),
Err(ref e) if e.kind() == io::ErrorKind::TimedOut => (),
Err(e) => eprintln!("{:?}", e),
}
for i in 0..127 {
if touch_active_1.load(Ordering::Relaxed) {
let mut touchbuffer: Vec<u8> = vec![0; 36];
touchbuffer[0] = 129;
touchbuffer[34] = i;
touchbuffer[35] = 128;
touchbuffer[35] = calc_checksum(&touchbuffer);
if touchbuffer[34] == 127 {touchbuffer[34] = 0};
let _ = writer_tx.send(touchbuffer);
}
} else {thread::sleep(Duration::from_millis(100))};
}
thread::sleep(Duration::from_millis(8));
}
});
}
loop {
let mut timing: Instant = Instant::now();
if timing.elapsed() >= Duration::from_millis(8) {
timing = Instant::now();
// let mut serialbuffer = vec![0; 1000];
// let mut wright= loop {
// match rport1.lock() {
// Ok(g) => {break g},
// Err(e) => ()
// }
// };
// let mut gright = rport2.lock().expect("hi");
// match gright.read(serialbuffer.as_mut_slice()) {
// Ok(t) => { println!("hi"); handle_data(&serialbuffer[..t].to_vec(), gright, wright, &rightparams, righttouchactive2.lock().unwrap()) },
// Err(ref e) if e.kind() == io::ErrorKind::TimedOut => (),
// Err(e) => eprintln!("{:?}", e),
// }
} else {thread::sleep(Duration::from_millis(8))}
thread::sleep(Duration::from_secs(1));
}
/* if left.scan_active {
if lefttiming.elapsed() >= Duration::from_millis(8) {
lefttiming = Instant::now();
tokio::spawn(async {wacca::touch_recv(lwport, ltouch, false)});
tokio::spawn(async {wacca::touch_send(lport, ltouch2)});
}
} else {
left.poll();
}
if right.scan_active {
if righttiming.elapsed() >= Duration::from_millis(8) {
righttiming = Instant::now();
tokio::spawn(async {wacca::touch_recv(rwport, rtouch, true)});
tokio::spawn(async {wacca::touch_send(rport, rtouch2)});
}
} else {
right.poll();
*/ //}
}

View file

@ -1,4 +0,0 @@
mod wacca;
fn main() {
println!("ffff")
}

View file

@ -1,322 +0,0 @@
use std::{io::{self, Write}, marker::StructuralEq, process::Command, str, sync::{Arc, Mutex, MutexGuard}, time::{Duration, Instant}};
use serialport::SerialPort;
fn fix_touch(byte: u8, side: bool) -> u8 {
if side {
println!(byte);
println!(byte.reverse_bits() >> 2);
byte.reverse_bits() >> 2
} else {
byte & 0x7f
}
}
pub struct UnitBoardVersionPacket {
pub sync_board_version: String,
pub unit_board_version: Vec<String>,
pub side: bool,
}
impl UnitBoardVersionPacket {
pub fn serialize(&self) -> Vec<u8> {
let mut s: Vec<u8> = vec![0xA8];
s.append(&mut self.sync_board_version.as_bytes().to_vec());
if self.side {s.push(0x4C)} else {s.push(0x52)};
for v in &self.unit_board_version {
s.append(&mut v.as_bytes().to_vec());
}
s.push(calc_checksum(&[s.as_slice(),vec![0x80].as_slice()].concat()));
//if self.side {s.push(104)} else {s.push(118)};
s
}
}
#[derive(Debug)]
pub struct CommandPacket {
pub out: bool,
pub wedge_id: u8,
pub command_id: u8,
pub data: Vec<u8>
}
impl CommandPacket {
pub fn serialize(&self) -> Vec<u8> {
let dir: u8 = if self.out { 0xE0 } else { 0xD0 };
let mut packet: Vec<u8> = vec![self.wedge_id+dir, self.command_id];
packet.extend(&self.data);
let tail: Vec<u8> = vec![calc_checksum(&packet),240];
return [packet, tail].concat();
}
pub fn new(mut data: Vec<u8>) -> Result<CommandPacket, &'static str> { //TODO: Rewrite this parser to be more lenient with incoming data (trailing zero's etc)
if data.len() < 4 {
return Err("Invalid Size")
}
if data[data.len()-1] == 0 {
data = data[..data.len()-1].to_vec();
}
let c: u8 = if data[1] == 0xA1 {
calc_checksum(&[data[0..data.len()-2].to_vec(), vec![0x80]].concat())
} else {
calc_checksum(&data[0..data.len()-2].to_vec())
};
let checksum: u8 = data[data.len()-2];
if c != checksum {
println!("aaa");
return Err("Invalid Checksum");
};
let a: (bool, u8) = match data[0] {
209..215 => (false, data[0]-208),
225..231 => (true, data[0]-224),
_ => (false,0)
};
if a.1 == 0 {return Err("Wedge ID out of bounds")}
let datalen: usize = if data.len() > 4 {
data.len()-3
} else {
2
};
return Ok(CommandPacket {
out: a.0,
wedge_id: a.1,
command_id: data[1],
data: data[2..datalen].to_vec()
})
}
}
pub struct SyncBoardParams<'a> {
pub param0000: &'a str,
pub param0016: &'a str,
pub param0032: &'a str,
pub sync_board_version: &'a str,
}
impl SyncBoardParams<'static> {
pub fn get() -> SyncBoardParams<'static> {
SyncBoardParams {
param0000: " 0 0 1 2 3 4 5 15 15 15 15 15 15 11 11 11",
param0016: " 11 11 11 128 103 103 115 138 127 103 105 111 126 113 95 100",
param0032: " 101 115 98 86 76 67 68 48 117 0 82 154 0 6 35 4",
sync_board_version: "190523",
}
}
}
pub fn calc_checksum(data: &Vec<u8>) -> u8 {
let mut checksum: u8 = 0;
for byte in data.iter() {
checksum ^= byte;
}
checksum
}
pub struct TouchLink<'a> {
pub scan_active: bool,
pub port: Arc<Mutex<Box<dyn SerialPort>>>,
pub sync_board_version: &'a str,
pub buffer: Vec<u8>,
pub buffer2: Vec<u8>,
pub syncboardparams: SyncBoardParams<'a>,
pub side: bool,
pub touchbuffer: Arc<Mutex<Vec<u8>>>,
pub wport: Arc<Mutex<Box<dyn SerialPort>>>,
pub time: Instant,
pub pollrate: Duration,
}
impl TouchLink<'_> {
/* pub fn poll(&mut self) {
let binding = self.port.clone();
let mut port: std::sync::MutexGuard<'_, Box<dyn SerialPort>> = binding.lock().expect("aaa");
match port.read(self.buffer.as_mut_slice()) {
Ok(t) => self.handle_data(&self.buffer[..t].to_vec(), port),
Err(ref e) if e.kind() == io::ErrorKind::TimedOut => (),
Err(e) => eprintln!("{:?}", e),
}
} */
pub fn handle_data(&mut self, buffer: &Vec<u8>, mut port: MutexGuard<'_, Box<dyn SerialPort>>, mut portw: MutexGuard<'_, Box<dyn SerialPort>>) {
match buffer[0] {
0xa0 => {
self.scan_active = false;
port.write(&[vec![buffer[0]], self.sync_board_version.as_bytes().to_vec(), vec![44]].concat()).unwrap();
},
0x77 => {},
0x20 => {
self.scan_active = false;
},
0xa2 => {
self.scan_active = false;
let _ = port.write(&[ 162, 63, 29, 0, 0, 0, 0 ]);
for i in 1..7 {
let packet: Result<CommandPacket, &str> = issue_command( ,CommandPacket { out: true, wedge_id: i, command_id: 0xA0, data: Vec::new() });
}
},
0x94 => {
self.scan_active = false;
for i in 1..7 {
let packet: Result<CommandPacket, &str> = issue_command( ,CommandPacket { out: true, wedge_id: i, command_id: 0x94, data: Vec::new() });
}
let _ = port.write(&[ 148, 0, 20, 0, 0, 0, 0 ]);
},
0xc9 => {
for i in 1..7 {
let packet: Result<CommandPacket, &str> = issue_command( ,CommandPacket { out: true, wedge_id: i, command_id: 0x90, data: vec![0x14, 0x07, 0x7F, 0x3F,] });
}
self.scan_active = true;
let _ = port.write(&[ 201, 0, 73, 0, 0, 0, 0 ]);
},
0xa8 => {
let mut versions: Vec<String> = Vec::new();
for i in 1..7 {
let packet = issue_command( ,CommandPacket { out: true, wedge_id: i, command_id: 0xA8, data: Vec::new() });
let data = packet.unwrap().data.to_owned();
let version = str::from_utf8(&data).expect("Error").to_string();
versions.push(version[..6].to_string());
}
let _ = port.write(&UnitBoardVersionPacket {
sync_board_version: self.sync_board_version.to_string(),
unit_board_version: versions,
side: self.side,
}.serialize());
},
0x72 => {
self.scan_active = false;
let param: &str = match buffer[3] {
0x30 => {self.syncboardparams.param0000}
0x31 => {self.syncboardparams.param0016}
0x33 => {self.syncboardparams.param0032}
_ => {""}
};
let _ = port.write(&[param.as_bytes(), &vec![calc_checksum(&param.as_bytes().to_vec())]].concat());
},
0x9a => {
self.scan_active = false;
},
_ => {},
}
}
pub fn issue_command(&mut self, command: CommandPacket) -> Result<CommandPacket, &str>{
let binding = self.wport.clone();
let mut wport = binding.lock().expect("yes");
let _ = wport.write(&command.serialize());
let data = loop {
match wport.read(self.buffer2.as_mut_slice()) {
Ok(t) => {break self.buffer2[..t].to_vec()},
Err(ref e) if e.kind() == io::ErrorKind::TimedOut => (),
Err(e) => eprintln!("{:?}", e),
}
};
CommandPacket::new(data)
}
}
pub fn handle_data(buffer: &Vec<u8>, mut port: std::sync::MutexGuard<'_, Box<dyn SerialPort>>, mut portw: std::sync::MutexGuard<'_, Box<dyn SerialPort>>, params: &SyncBoardParams, scan_active: MutexGuard<'_, bool>) {
match buffer[0] {
0xa0 => {
self.scan_active = false;
port.write(&[vec![buffer[0]], params.sync_board_version.as_bytes().to_vec(), vec![44]].concat()).unwrap();
},
0x77 => {},
0x20 => {
self.scan_active = false;
},
0xa2 => {
self.scan_active = false;
let _ = port.write(&[ 162, 63, 29, 0, 0, 0, 0 ]);
for i in 1..7 {
let packet: Result<CommandPacket, &str> = issue_command(portw ,CommandPacket { out: true, wedge_id: i, command_id: 0xA0, data: Vec::new() });
}
},
0x94 => {
self.scan_active = false;
for i in 1..7 {
let packet: Result<CommandPacket, &str> = issue_command(portw ,CommandPacket { out: true, wedge_id: i, command_id: 0x94, data: Vec::new() });
}
let _ = port.write(&[ 148, 0, 20, 0, 0, 0, 0 ]);
},
0xc9 => {
for i in 1..7 {
let packet: Result<CommandPacket, &str> = issue_command(portw ,CommandPacket { out: true, wedge_id: i, command_id: 0x90, data: vec![0x14, 0x07, 0x7F, 0x3F,] });
}
self.scan_active = true;
let _ = port.write(&[ 201, 0, 73, 0, 0, 0, 0 ]);
},
0xa8 => {
let mut versions: Vec<String> = Vec::new();
for i in 1..7 {
let packet = issue_command(portw ,CommandPacket { out: true, wedge_id: i, command_id: 0xA8, data: Vec::new() });
let data = packet.unwrap().data.to_owned();
let version = str::from_utf8(&data).expect("Error").to_string();
versions.push(version[..6].to_string());
}
let _ = port.write(&UnitBoardVersionPacket {
sync_board_version: params.sync_board_version.to_string(),
unit_board_version: versions,
side: self.side,
}.serialize());
},
0x72 => {
self.scan_active = false;
let param: &str = match buffer[3] {
0x30 => {params.param0000}
0x31 => {params.param0016}
0x33 => {params.param0032}
_ => {""}
};
let _ = port.write(&[param.as_bytes(), &vec![calc_checksum(&param.as_bytes().to_vec())]].concat());
},
0x9a => {
self.scan_active = false;
},
_ => {},
}
}
pub fn touch_recv(port: Arc<Mutex<Box<dyn SerialPort>>>, touchbuffer: Arc<Mutex<Vec<u8>>>, side: bool) {
let mut port = port.lock().expect("yes");
let mut touchbuffer = touchbuffer.lock().expect("yes");
let mut serialbuffer = vec![0; 1000];
for i in 1..7 {
let r: usize = 7-i;
let _ = port.write(&CommandPacket { out: true, wedge_id: i as u8, command_id: 0xA1, data: Vec::new() }.serialize());
let data = loop {
match port.read(serialbuffer.as_mut_slice()) {
Ok(t) => {break serialbuffer[..t].to_vec()},
Err(ref e) if e.kind() == io::ErrorKind::TimedOut => (),
Err(e) => eprintln!("{:?}", e),
}
};
if let Ok(ret) = CommandPacket::new(data) {
touchbuffer[r as usize] = fix_touch(ret.data[0], side);
touchbuffer[(r+6) as usize] = fix_touch(ret.data[1], side);
touchbuffer[(r+12) as usize] = fix_touch(ret.data[2], side);
touchbuffer[(r+18) as usize] = fix_touch(ret.data[3], side);
}
}
}
pub fn issue_command(mut wport: std::sync::MutexGuard<'_, Box<dyn SerialPort>>, command: CommandPacket) -> Result<CommandPacket, &'static str>{
let _ = wport.write(&command.serialize());
let mut serialbuffer = vec![0; 1000];
let data = loop {
match wport.read(serialbuffer.as_mut_slice()) {
Ok(t) => {break serialbuffer[..t].to_vec()},
Err(ref e) if e.kind() == io::ErrorKind::TimedOut => (),
Err(e) => eprintln!("{:?}", e),
}
};
CommandPacket::new(data)
}
pub fn touch_send(port: Arc<Mutex<Box<dyn SerialPort>>>, touchbuffer: Arc<Mutex<Vec<u8>>>) {
let mut port = port.lock().unwrap();
let mut touchbuffer = touchbuffer.lock().unwrap();
touchbuffer[0] = 129;
touchbuffer[34] = touchbuffer[34] + 1;
touchbuffer[35] = 128;
touchbuffer[35] = calc_checksum(&touchbuffer);
if touchbuffer[34] == 127 {touchbuffer[34] = 0};
let _ = port.write(&touchbuffer);
}

View file

@ -1,15 +1,40 @@
use std::{io::{self, Write}, str, sync::{atomic::{AtomicBool, Ordering}, mpsc, Arc, Mutex, MutexGuard}, time::{Duration, Instant}};
use std::sync::{atomic::{AtomicBool, Ordering}, Arc};
use serialport::SerialPort;
use serial2::SerialPort;
fn fix_touch(byte: u8, side: bool) -> u8 {
if side {
byte.reverse_bits() >> 3
} else {
byte & 0x7f
pub struct SyncBoardParams<'a> {
pub param0000: &'a str,
pub param0016: &'a str,
pub param0032: &'a str,
pub sync_board_version: &'a str,
pub side: bool,
}
impl SyncBoardParams<'static> {
pub fn get(side: &bool) -> SyncBoardParams<'static> {
SyncBoardParams {
param0000: " 0 0 1 2 3 4 5 15 15 15 15 15 15 11 11 11",
param0016: " 11 11 11 128 103 103 115 138 127 103 105 111 126 113 95 100",
param0032: " 101 115 98 86 76 67 68 48 117 0 82 154 0 6 35 4",
sync_board_version: "190523",
side: *side,
}
}
}
pub struct TouchBinding {
pub game_serial: Arc<SerialPort>,
pub side: bool,
}
#[derive(Debug)]
pub struct CommandPacket {
pub out: bool,
pub wedge_id: u8,
pub command_id: u8,
pub data: Vec<u8>
}
pub struct UnitBoardVersionPacket {
pub sync_board_version: String,
pub unit_board_version: Vec<String>,
@ -29,13 +54,6 @@ impl UnitBoardVersionPacket {
s
}
}
#[derive(Debug)]
pub struct CommandPacket {
pub out: bool,
pub wedge_id: u8,
pub command_id: u8,
pub data: Vec<u8>
}
impl CommandPacket {
pub fn serialize(&self) -> Vec<u8> {
@ -84,25 +102,6 @@ impl CommandPacket {
}
}
pub struct SyncBoardParams<'a> {
pub param0000: &'a str,
pub param0016: &'a str,
pub param0032: &'a str,
pub sync_board_version: &'a str,
pub side: bool,
}
impl SyncBoardParams<'static> {
pub fn get(side: bool) -> SyncBoardParams<'static> {
SyncBoardParams {
param0000: " 0 0 1 2 3 4 5 15 15 15 15 15 15 11 11 11",
param0016: " 11 11 11 128 103 103 115 138 127 103 105 111 126 113 95 100",
param0032: " 101 115 98 86 76 67 68 48 117 0 82 154 0 6 35 4",
sync_board_version: "190523",
side,
}
}
}
pub fn calc_checksum(data: &Vec<u8>) -> u8 {
let mut checksum: u8 = 0;
for byte in data.iter() {
@ -111,61 +110,35 @@ pub fn calc_checksum(data: &Vec<u8>) -> u8 {
checksum
}
pub struct TouchLink<'a> {
pub scan_active: bool,
pub port: Arc<Mutex<Box<dyn SerialPort>>>,
pub sync_board_version: &'a str,
pub buffer: Vec<u8>,
pub buffer2: Vec<u8>,
pub syncboardparams: SyncBoardParams<'a>,
pub side: bool,
pub touchbuffer: Arc<Mutex<Vec<u8>>>,
pub wport: Arc<Mutex<Box<dyn SerialPort>>>,
pub time: Instant,
pub pollrate: Duration,
}
pub fn handle_data(buffer: &Vec<u8>, mut port: std::sync::MutexGuard<'_, Box<dyn SerialPort>>, mut portw: std::sync::MutexGuard<'_, Box<dyn SerialPort>>, params: &SyncBoardParams, mut scan_active: Arc<AtomicBool>) {
pub fn handle_data(buffer: &Vec<u8>, params: &SyncBoardParams, mut scan_active: Arc<AtomicBool>) -> Option<Vec<u8>> {
match buffer[0] {
0xa0 => {
scan_active.store(false, Ordering::Relaxed);
port.write(&[vec![buffer[0]], params.sync_board_version.as_bytes().to_vec(), vec![44]].concat()).unwrap();
return Some([vec![buffer[0]], params.sync_board_version.as_bytes().to_vec(), vec![44]].concat().to_vec());
},
0x77 => {
return None;
},
0x77 => {},
0x20 => {
scan_active.store(false, Ordering::Relaxed);
return None;
},
0xa2 => {
scan_active.store(false, Ordering::Relaxed);
let _ = port.write(&[ 162, 63, 29, 0, 0, 0, 0 ]);
for i in 1..7 {
let packet: Result<CommandPacket, &str> = issue_command(&mut portw ,CommandPacket { out: true, wedge_id: i, command_id: 0xA0, data: Vec::new() });
}
return Some(vec![ 162, 63, 29, 0, 0, 0, 0 ]);
},
0x94 => {
scan_active.store(false, Ordering::Relaxed);
for i in 1..7 {
let packet: Result<CommandPacket, &str> = issue_command(&mut portw ,CommandPacket { out: true, wedge_id: i, command_id: 0x94, data: Vec::new() });
}
let _ = port.write(&[ 148, 0, 20, 0, 0, 0, 0 ]);
return Some(vec![ 148, 0, 20, 0, 0, 0, 0 ]);
},
0xc9 => {
for i in 1..7 {
let packet: Result<CommandPacket, &str> = issue_command(&mut portw ,CommandPacket { out: true, wedge_id: i, command_id: 0x90, data: vec![0x14, 0x07, 0x7F, 0x3F,] });
}
scan_active.store(true, Ordering::Relaxed);
let _ = port.write(&[ 201, 0, 73, 0, 0, 0, 0 ]);
return Some(vec![ 201, 0, 73, 0, 0, 0, 0 ]);
},
0xa8 => {
let mut versions: Vec<String> = Vec::new();
for i in 1..7 {
let packet = issue_command(&mut portw ,CommandPacket { out: true, wedge_id: i, command_id: 0xA8, data: Vec::new() });
let data = packet.unwrap().data.to_owned();
let version = str::from_utf8(&data).expect("Error").to_string();
versions.push(version[..6].to_string());
}
let _ = port.write(&UnitBoardVersionPacket {
//let mut versions: Vec<String> = Vec::new();
let mut versions = vec!["190523".to_string(), "190523".to_string(), "190523".to_string(), "190523".to_string(), "190523".to_string(), "190523".to_string()];
return Some(UnitBoardVersionPacket {
sync_board_version: params.sync_board_version.to_string(),
unit_board_version: versions,
side: params.side,
@ -179,61 +152,14 @@ pub fn handle_data(buffer: &Vec<u8>, mut port: std::sync::MutexGuard<'_, Box<dyn
0x33 => {params.param0032}
_ => {""}
};
let _ = port.write(&[param.as_bytes(), &vec![calc_checksum(&param.as_bytes().to_vec())]].concat());
return Some([param.as_bytes(), &vec![calc_checksum(&param.as_bytes().to_vec())]].concat())
},
0x9a => {
scan_active.store(false, Ordering::Relaxed);
return None;
},
_ => {
return None;
},
_ => {},
}
}
pub fn touch_recv(port: Arc<Mutex<Box<dyn SerialPort>>>, side: bool) -> Vec<u8> {
let mut port = port.lock().expect("yes");
let mut serialbuffer = vec![0; 1000];
let mut datar = vec!(0; 24);
for i in 1..7 {
let r: usize = 7-i;
let _ = port.write(&CommandPacket { out: true, wedge_id: i as u8, command_id: 0xA1, data: Vec::new() }.serialize());
let data = loop {
match port.read(serialbuffer.as_mut_slice()) {
Ok(t) => {break serialbuffer[..t].to_vec()},
Err(ref e) if e.kind() == io::ErrorKind::TimedOut => (),
Err(e) => eprintln!("{:?}", e),
}
};
if let Ok(ret) = CommandPacket::new(data) {
if ret.data.len() >= 4 {
datar[r-1 as usize] = fix_touch(ret.data[0], side);
datar[(r+6)-1 as usize] = fix_touch(ret.data[1], side);
datar[(r+12)-1 as usize] = fix_touch(ret.data[2], side);
datar[(r+18)-1 as usize] = fix_touch(ret.data[3], side);
}
}
}
return datar;
}
pub fn issue_command(mut wport: &mut std::sync::MutexGuard<'_, Box<dyn SerialPort>>, command: CommandPacket) -> Result<CommandPacket, &'static str>{
let _ = wport.write(&command.serialize());
let mut serialbuffer = vec![0; 1000];
let data = loop {
match wport.read(serialbuffer.as_mut_slice()) {
Ok(t) => {break serialbuffer[..t].to_vec()},
Err(ref e) if e.kind() == io::ErrorKind::TimedOut => (),
Err(e) => eprintln!("{:?}", e),
}
};
CommandPacket::new(data)
}
pub fn touch_send(port: Arc<Mutex<Box<dyn SerialPort>>>, touchbuffer: &mut Vec<u8>) {
let mut port = port.lock().unwrap();
touchbuffer[0] = 129;
touchbuffer[34] = touchbuffer[34] + 1;
touchbuffer[35] = 128;
touchbuffer[35] = calc_checksum(&touchbuffer);
if touchbuffer[34] == 127 {touchbuffer[34] = 0};
let _ = port.write(&touchbuffer);
}