Skip to content
Draft
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
499 changes: 499 additions & 0 deletions Cargo.lock

Large diffs are not rendered by default.

24 changes: 24 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[workspace]
resolver = "2"
members = [
"src/beslib",
"src/bestool",
]

[workspace.package]
authors = ["Ben V. Brown <ralim@ralimtek.com>", "Dom Rodriguez <shymega@shymega.org.uk>"]
edition = "2021"
homepage = "https://github.com/Ralim/bestool"
readme = "/README.md"
repository = "https://github.com/Ralim/bestool.git"
rust-version = "1.67.0"
version = "0.3.0"

[workspace.dependencies]
clap = { version = "4.5.1", features = ["derive"] }
crc = "3.0.1"
serde = { version = "1.0.196", features = ["derive"] }
serde_json = "1.0.113"
serialport = "4.3.0"
tracing = "0.1.40"
tracing-subscriber = "0.3.18"
15 changes: 15 additions & 0 deletions src/beslib/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
authors = { workspace = true }
description = "Support library for `bestool`; a command-line utility for BES2300 chips."
edition = { workspace = true }
homepage = { workspace = true }
# license = { workspace = true } # TODO: Specify license with REUSE.
name = "beslib"
repository = { workspace = true }
rust-version = { workspace = true }
version = { workspace = true }

[dependencies]
crc = { workspace = true }
serialport = { workspace = true }
tracing = { workspace = true }
File renamed without changes.
File renamed without changes.
File renamed without changes.
6 changes: 6 additions & 0 deletions src/beslib/src/consts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pub struct BesConsts;

impl BesConsts {
pub const BES_DEFAULT_PROGRAMMING_BAUDRATE: u32 = 921_600;
pub const BES_SYNC: u8 = 0xBE;
}
25 changes: 25 additions & 0 deletions src/beslib/src/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use std::fmt;
use std::error;
use std::io::Error as IoError;

#[derive(Debug)]
pub enum BesLinkError {
IoError(IoError),
}

impl error::Error for BesLinkError {}

impl fmt::Display for BesLinkError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
BesLinkError::IoError(ref e) => write!(f, "IO error: {}", e)

}
}
}

impl From<IoError> for BesLinkError {
fn from(e: IoError) -> Self {
BesLinkError::IoError(e)
}
}
3 changes: 3 additions & 0 deletions src/beslib/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod consts;
pub mod message;
pub mod utils;
138 changes: 138 additions & 0 deletions src/beslib/src/message.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
use std::io::{Result as IoResult, Write};
use crate::utils::calculate_message_checksum;
use tracing::{debug, info};

#[derive(Default, Debug, Eq, PartialEq, Clone, Copy)]
#[repr(u8)]
pub enum MessageKind {
DeviceCommand = 0x00, // General commands to the device
FlashRead = 0x03, // Debugging message that lets you dump from address space
Sync = 0x50, // Seems to be used at boot for locking with ROM
StartProgrammer = 0x53,
ProgrammerRunning = 0x54,
ProgrammerStart = 0x55,
ProgrammerInit = 0x60,
EraseBurnStart = 0x61,
FlashBurnData = 0x62,
FlashCommand = 0x65, // Suspect used to push extra commands to flash controller/chip/die
#[default]
UnknownOrInfo = 0x66, // Unknown at this point in time, but references "OR Info"; suspect NOR flash info
}

impl From<MessageKind> for u8 {
fn from(v: MessageKind) -> Self {
v as Self
}
}

impl From<u8> for MessageKind {
fn from(v: u8) -> Self {
match v {
0x00 => Self::DeviceCommand,
0x03 => Self::FlashRead,
0x50 => Self::Sync,
0x53 => Self::StartProgrammer,
0x54 => Self::ProgrammerRunning,
0x55 => Self::ProgrammerStart,
0x60 => Self::ProgrammerInit,
0x61 => Self::EraseBurnStart,
0x62 => Self::FlashBurnData,
0x65 => Self::FlashCommand,
_ => Self::default(),
}
}
}

#[derive(Debug, Eq, PartialEq, Clone)]
pub struct BesMessage {
pub sync: u8,
pub msg_type: MessageKind,
pub payload: Vec<u8>,
pub checksum: u8,
}

impl From<BesMessage> for Vec<u8> {
fn from(mut val: BesMessage) -> Self {
let mut packet: Vec<u8> = vec![];
packet.push(val.sync);
packet.push(val.msg_type.into());
packet.append(&mut val.payload);
packet.push(val.checksum);

packet
}
}

impl From<&mut BesMessage> for Vec<u8> {
fn from(val: &mut BesMessage) -> Self {
let mut packet: Vec<u8> = vec![];
packet.push(val.sync);
packet.push(val.msg_type.into());
packet.append(&mut val.payload);
packet.push(val.checksum);

packet
}
}

impl From<&BesMessage> for Vec<u8> {
fn from(val: &BesMessage) -> Self {
let mut val = val.clone();
let mut packet: Vec<u8> = vec![];
packet.push(val.sync);
packet.push(val.msg_type.into());
packet.append(&mut val.payload);
packet.push(val.checksum);

packet
}
}

impl From<Vec<u8>> for BesMessage {
fn from(v: Vec<u8>) -> Self {
let mut msg = BesMessage {
sync: v[0],
msg_type: MessageKind::Sync,
payload: vec![],
checksum: v[v.len() - 1],
};

msg.msg_type = v[1].into();
msg.payload = v[2..v.len() - 1].to_vec();

msg
}
}

impl BesMessage {
pub fn set_checksum(&mut self) {
let mut v: Vec<u8> = self.into();
v.pop();
self.checksum = crate::utils::calculate_message_checksum(&v);
}

pub fn send(self, out: &mut dyn Write) -> IoResult<()>
{
let packet: Vec<u8>;

#[allow(clippy::unnecessary_fallible_conversions)]
if let Ok(p) = self.clone().try_into() {
packet = p;
} else {
panic!("Failed to convert BesMessage to Vec<u8>");
}// Return Error.

return match out.write_all(packet.as_slice()) {
Ok(_) => {
debug!("Sent message to chip: {packet:X?}", packet = packet);
debug!("Wrote {len} bytes.", len = packet.len());

// TODO: Should the caller flush the target device? (i.e, serial port).

info!("Sent message type: {:?}", self.msg_type);
Ok(())
}
Err(e) => Err(e),
};
}
}
3 changes: 3 additions & 0 deletions src/beslib/src/utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod checksum;

pub use self::checksum::*;
25 changes: 25 additions & 0 deletions src/beslib/src/utils/checksum.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use std::io::Error as BESLinkError;

pub fn validate_packet_checksum(packet: &[u8]) -> Result<(), BESLinkError> {
let checksum = calculate_message_checksum(&packet[1..packet.len()]);
if checksum == packet[packet.len() - 1] {
return Ok(());
}
// let e = BESLinkError::BadChecksumError {
// failed_packet: packet.to_vec(),
// got: packet[packet.len() - 1],
// wanted: checksum,
// };
// warn!("Bad Checksum!! {:?}", e);

Err(BESLinkError::other("Error."))
}

pub fn calculate_message_checksum(packet: &[u8]) -> u8 {
let mut sum: u32 = 0;
for b in packet {
sum += u32::from(*b);
sum &= 0xFF;
}
(0xFF - sum) as u8
}
Loading