use parser from shared library

This commit is contained in:
Vinzenz Schroeter 2024-05-10 20:20:58 +02:00
parent 88409faa02
commit bce0c48c4d
4 changed files with 29 additions and 145 deletions

2
Cargo.lock generated
View file

@ -2151,7 +2151,7 @@ dependencies = [
[[package]] [[package]]
name = "servicepoint2" name = "servicepoint2"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/kaesaecracker/servicepoint.git#9eaa7462bccee02f698779b0fb4b9c1e9676bc60" source = "git+https://github.com/kaesaecracker/servicepoint.git#c7456f0a67b5488cca777ea702144cd9996698c0"
dependencies = [ dependencies = [
"num", "num",
"num-derive", "num-derive",

View file

@ -2,7 +2,6 @@
mod font; mod font;
mod gui; mod gui;
mod protocol;
mod upd_loop; mod upd_loop;
use std::default::Default; use std::default::Default;

View file

@ -1,79 +0,0 @@
use num_derive::{FromPrimitive, ToPrimitive};
use servicepoint2::CommandCode;
use std::mem::size_of;
#[repr(C)]
#[derive(Debug)]
pub struct HdrWindow {
pub command: CommandCode,
pub x: u16,
pub y: u16,
pub w: u16,
pub h: u16,
}
/*
#[repr(C)]
pub struct HdrBitmap {
pub command: DisplayCommand,
pub offset: u16,
pub length: u16,
pub subcommand: DisplaySubcommand,
reserved: u16,
}
*/
#[repr(u16)]
#[derive(Debug, FromPrimitive, ToPrimitive)]
pub enum DisplaySubcommand {
SubCmdBitmapNormal = 0x0,
SubCmdBitmapCompressZ = 0x677a,
SubCmdBitmapCompressBz = 0x627a,
SubCmdBitmapCompressLz = 0x6c7a,
SubCmdBitmapCompressZs = 0x7a73,
}
#[derive(Debug)]
pub enum ReadHeaderError {
BufferTooSmall,
WrongCommandEndianness(u16, CommandCode),
InvalidCommand(u16),
}
impl HdrWindow {
pub fn from_buffer(buffer: &[u8]) -> Result<HdrWindow, ReadHeaderError> {
assert_eq!(size_of::<HdrWindow>(), 10, "invalid struct size");
if buffer.len() < size_of::<HdrWindow>() {
return Err(ReadHeaderError::BufferTooSmall);
}
let command_u16 = Self::read_beu16(&buffer[0..=1]);
return match CommandCode::from_primitive(command_u16) {
Some(command) => Ok(HdrWindow {
command,
x: Self::read_beu16(&buffer[2..=3]),
y: Self::read_beu16(&buffer[4..=5]),
w: Self::read_beu16(&buffer[6..=7]),
h: Self::read_beu16(&buffer[8..=9]),
}),
None => {
let maybe_command = CommandCode::from_primitive(u16::swap_bytes(command_u16));
return match maybe_command {
None => Err(ReadHeaderError::InvalidCommand(command_u16)),
Some(command) => Err(ReadHeaderError::WrongCommandEndianness(
command_u16,
command,
)),
};
}
};
}
fn read_beu16(buffer: &[u8]) -> u16 {
let buffer: [u8; 2] = buffer
.try_into()
.expect("cannot read u16 from buffer with size != 2");
return u16::from_be_bytes(buffer);
}
}

View file

@ -1,8 +1,7 @@
use crate::font::BitmapFont; use crate::font::BitmapFont;
use crate::protocol::{HdrWindow, ReadHeaderError};
use crate::DISPLAY; use crate::DISPLAY;
use log::{debug, error, info, warn}; use log::{debug, error, info, warn};
use servicepoint2::{PixelGrid, PIXEL_WIDTH, TILE_SIZE, CommandCode}; use servicepoint2::{Command, Origin, Packet, PixelGrid, PIXEL_WIDTH, TILE_SIZE, Window, Size};
use std::io::ErrorKind; use std::io::ErrorKind;
use std::net::{ToSocketAddrs, UdpSocket}; use std::net::{ToSocketAddrs, UdpSocket};
use std::sync::mpsc; use std::sync::mpsc;
@ -47,7 +46,10 @@ impl UdpThread {
); );
} }
Self::handle_package(&mut buf[..amount], &font); let vec = buf[..amount].to_vec();
let package = servicepoint2::Packet::from(vec);
Self::handle_package(package, &font);
} }
}); });
@ -59,53 +61,29 @@ impl UdpThread {
self.thread.join().expect("could not wait on udp thread"); self.thread.join().expect("could not wait on udp thread");
} }
fn handle_package(received: &mut [u8], font: &BitmapFont) { fn handle_package(received: Packet, font: &BitmapFont) {
let header = match HdrWindow::from_buffer(&received[..10]) { // TODO handle error case
Err(ReadHeaderError::BufferTooSmall) => { let command = Command::try_from(received).unwrap();
error!("received a packet that is too small");
return;
}
Err(ReadHeaderError::InvalidCommand(command_u16)) => {
error!("received invalid command {}", command_u16);
return;
}
Err(ReadHeaderError::WrongCommandEndianness(command_u16, command_swapped)) => {
error!(
"The reversed byte order of {} matches command {:?}, you are probably sending the wrong endianness",
command_u16, command_swapped
);
return;
}
Ok(value) => value,
};
let payload = &received[10..]; match command {
Command::Clear => {
info!(
"received from {:?} (and {} bytes of payload)",
header,
payload.len()
);
match header.command {
CommandCode::Clear => {
info!("clearing display"); info!("clearing display");
for v in unsafe { DISPLAY.iter_mut() } { for v in unsafe { DISPLAY.iter_mut() } {
*v = false; *v = false;
} }
} }
CommandCode::HardReset => { Command::HardReset => {
warn!("display shutting down"); warn!("display shutting down");
return; return;
} }
CommandCode::BitmapLinearWin => { Command::BitmapLinearWin(Origin(x, y), pixels) => {
Self::print_bitmap_linear_win(&header, payload); Self::print_pixel_grid(x as usize, y as usize, &pixels);
} }
CommandCode::Cp437Data => { Command::Cp437Data(window, payload) => {
Self::print_cp437_data(&header, payload, font); Self::print_cp437_data(window, &payload, font);
} }
_ => { _ => {
error!("command {:?} not implemented yet", header.command); error!("command {:?} not implemented yet", command);
} }
} }
} }
@ -123,35 +101,18 @@ impl UdpThread {
return false; return false;
} }
fn print_bitmap_linear_win(header: &HdrWindow, payload: &[u8]) { fn print_cp437_data(window: Window, payload: &[u8], font: &BitmapFont) {
if !Self::check_payload_size(payload, header.w as usize * header.h as usize) { let Window(Origin(x,y), Size(w, h)) = window;
if !UdpThread::check_payload_size(payload, (w * h) as usize) {
return; return;
} }
let pixel_grid = PixelGrid::load( for char_y in 0usize..h as usize {
header.w as usize * TILE_SIZE as usize, for char_x in 0usize..w as usize {
header.h as usize, let char_code = payload[char_y * w as usize + char_x];
payload,
);
Self::print_pixel_grid( let tile_x = char_x + x as usize;
header.x as usize * TILE_SIZE as usize, let tile_y = char_y + y as usize;
header.y as usize,
&pixel_grid,
);
}
fn print_cp437_data(header: &HdrWindow, payload: &[u8], font: &BitmapFont) {
if !UdpThread::check_payload_size(payload, (header.w * header.h) as usize) {
return;
}
for char_y in 0usize..header.h as usize {
for char_x in 0usize..header.w as usize {
let char_code = payload[char_y * header.w as usize + char_x];
let tile_x = char_x + header.x as usize;
let tile_y = char_y + header.y as usize;
let bitmap = font.get_bitmap(char_code); let bitmap = font.get_bitmap(char_code);
Self::print_pixel_grid( Self::print_pixel_grid(
@ -164,7 +125,10 @@ impl UdpThread {
} }
fn print_pixel_grid(offset_x: usize, offset_y: usize, pixels: &PixelGrid) { fn print_pixel_grid(offset_x: usize, offset_y: usize, pixels: &PixelGrid) {
debug!("printing {}x{} grid at {offset_x} {offset_y}", pixels.width, pixels.height); debug!(
"printing {}x{} grid at {offset_x} {offset_y}",
pixels.width, pixels.height
);
for inner_y in 0..pixels.height { for inner_y in 0..pixels.height {
for inner_x in 0..pixels.width { for inner_x in 0..pixels.width {
let is_set = pixels.get(inner_x, inner_y); let is_set = pixels.get(inner_x, inner_y);