1
0
Fork 0

proto fw: add rx crc check

This commit is contained in:
morgan 2024-10-03 17:38:48 +08:00
parent bea80d0c1e
commit 0f9be29f4e
1 changed files with 58 additions and 14 deletions

View File

@ -16,16 +16,32 @@ const MEM_LEN: usize = 0x200;
#[derive(Debug)]
pub enum Error {
BufferError,
CorruptedPacket,
CtrlAckError(u8),
LinkDown,
UnknownPacket(u8),
}
#[derive(Debug)]
pub enum CtrlError {
AddressReadOnly,
AddressWriteOnly,
CRCFailed,
DataSizeDifferent,
InvalidAddress,
InvalidData,
InvalidOpcode,
MalformedPacket,
SizeToolarge,
}
impl From<IoError> for Error {
fn from(_: IoError) -> Error {
Error::BufferError
}
}
#[derive(Debug)]
pub enum Packet {
// Upconn packet
CtrlRead {
@ -56,13 +72,13 @@ pub enum Packet {
// Downconn packet
CtrlAck {
ackcode: u8,
length: u8,
length: u32,
data: [u8; DATA_MAXSIZE],
},
CtrlAckWithTag {
tag: u8,
ackcode: u8,
length: u8,
length: u32,
data: [u8; DATA_MAXSIZE],
},
CtrlAckNoData {
@ -88,18 +104,26 @@ fn read_word(reader: &mut Cursor<&mut [u8]>) -> Result<u32, Error> {
}
impl Packet {
pub fn read_from(reader: &mut Cursor<&mut [u8]>, packet_type: u8) -> Result<(), Error> {
pub fn read_from(reader: &mut Cursor<&mut [u8]>, packet_type: u8) -> Result<Self, Error> {
match packet_type {
0x03 => {
let ackcode4x = read_word(reader);
println!("ackcode4x = {:#010X}", ackcode4x.unwrap());
let len = read_word(reader);
println!("len = {:#010X}", len.unwrap());
let ackcode: u8 = (read_word(reader)? & 0xFF) as u8;
let length = read_word(reader)?;
let mut data: [u8; DATA_MAXSIZE] = [0; DATA_MAXSIZE];
if ackcode == 0x00 || ackcode == 0x04 {
reader.read(&mut data[0..length as usize])?;
};
match ackcode {
0x00 | 0x04 => return Ok(Packet::CtrlAck { ackcode, length, data }),
0x01 => return Ok(Packet::CtrlAckNoData { ackcode }),
_ => return Err(Error::CtrlAckError(ackcode)),
}
0x06 => {}
_ => {}
}
Ok(())
0x06 => return Err(Error::UnknownPacket(packet_type)),
_ => return Err(Error::UnknownPacket(packet_type)),
}
}
pub fn write_to(&self, writer: &mut Cursor<&mut [u8]>) -> Result<(), Error> {
// CoaXpress use big endian
@ -146,10 +170,13 @@ impl Packet {
if ackcode == 0x00 || ackcode == 0x04 {
writer.write(&[0x00, 0x00, 0x00, length])?;
writer.write(&data[0..length as usize])?;
}
print_packet(&writer.get_ref()[4..writer.position()]);
let checksum = crc32::checksum_ieee(&writer.get_ref()[4..writer.position()]);
writer.write(&(!checksum).to_le_bytes())?;
}
}
_ => return Err(Error::UnknownPacket(0)),
}
// Section 9.2.2.2 (CXP-001-2021)
@ -177,9 +204,26 @@ pub fn receive(channel: usize) -> Result<(), Error> {
let mut reader = Cursor::new(slice::from_raw_parts_mut(ptr as *mut u8, MEM_LEN));
let packet_type = (CXP[channel].downconn_packet_type_read)();
Packet::read_from(&mut reader, packet_type);
let packet = Packet::read_from(&mut reader, packet_type)?;
println!("{:?}", packet);
// print_packet(slice::from_raw_parts_mut(ptr as *mut u8, MEM_LEN));
// Section 9.2.2.2 (CXP-001-2021)
// Only Control packet need CRC32 appended in the end of the packet
// CoaXpress use the polynomial of IEEE-802.3 (Ethernet) CRC but the checksum calculation is different
// Also, the calculation does not include the first 4 bytes of packet_type
if packet_type == 0x03 || packet_type == 0x06 {
let checksum_at = reader.position();
let checksum = (!crc::crc32::checksum_ieee(&reader.get_ref()[0..checksum_at])).swap_bytes();
println!("checksum location = {:#010X}", checksum_at);
println!("calculated checksum = {:#010X}", checksum);
println!("read checksum = {:#010X}", read_word(&mut reader)?);
reader.set_position(checksum_at);
if read_word(&mut reader)? != checksum {
return Err(Error::CorruptedPacket);
}
}
print_packet(slice::from_raw_parts_mut(ptr as *mut u8, MEM_LEN));
}
Ok(())
}