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)] #[derive(Debug)]
pub enum Error { pub enum Error {
BufferError, BufferError,
CorruptedPacket,
CtrlAckError(u8),
LinkDown, LinkDown,
UnknownPacket(u8), UnknownPacket(u8),
} }
#[derive(Debug)]
pub enum CtrlError {
AddressReadOnly,
AddressWriteOnly,
CRCFailed,
DataSizeDifferent,
InvalidAddress,
InvalidData,
InvalidOpcode,
MalformedPacket,
SizeToolarge,
}
impl From<IoError> for Error { impl From<IoError> for Error {
fn from(_: IoError) -> Error { fn from(_: IoError) -> Error {
Error::BufferError Error::BufferError
} }
} }
#[derive(Debug)]
pub enum Packet { pub enum Packet {
// Upconn packet // Upconn packet
CtrlRead { CtrlRead {
@ -56,13 +72,13 @@ pub enum Packet {
// Downconn packet // Downconn packet
CtrlAck { CtrlAck {
ackcode: u8, ackcode: u8,
length: u8, length: u32,
data: [u8; DATA_MAXSIZE], data: [u8; DATA_MAXSIZE],
}, },
CtrlAckWithTag { CtrlAckWithTag {
tag: u8, tag: u8,
ackcode: u8, ackcode: u8,
length: u8, length: u32,
data: [u8; DATA_MAXSIZE], data: [u8; DATA_MAXSIZE],
}, },
CtrlAckNoData { CtrlAckNoData {
@ -88,18 +104,26 @@ fn read_word(reader: &mut Cursor<&mut [u8]>) -> Result<u32, Error> {
} }
impl Packet { 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 { match packet_type {
0x03 => { 0x03 => {
let ackcode4x = read_word(reader); let ackcode: u8 = (read_word(reader)? & 0xFF) as u8;
println!("ackcode4x = {:#010X}", ackcode4x.unwrap()); let length = read_word(reader)?;
let len = read_word(reader);
println!("len = {:#010X}", len.unwrap()); 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> { pub fn write_to(&self, writer: &mut Cursor<&mut [u8]>) -> Result<(), Error> {
// CoaXpress use big endian // CoaXpress use big endian
@ -146,10 +170,13 @@ impl Packet {
if ackcode == 0x00 || ackcode == 0x04 { if ackcode == 0x00 || ackcode == 0x04 {
writer.write(&[0x00, 0x00, 0x00, length])?; writer.write(&[0x00, 0x00, 0x00, length])?;
writer.write(&data[0..length as usize])?; 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()]); let checksum = crc32::checksum_ieee(&writer.get_ref()[4..writer.position()]);
writer.write(&(!checksum).to_le_bytes())?; writer.write(&(!checksum).to_le_bytes())?;
} }
}
_ => return Err(Error::UnknownPacket(0)), _ => return Err(Error::UnknownPacket(0)),
} }
// Section 9.2.2.2 (CXP-001-2021) // 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 mut reader = Cursor::new(slice::from_raw_parts_mut(ptr as *mut u8, MEM_LEN));
let packet_type = (CXP[channel].downconn_packet_type_read)(); 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(()) Ok(())
} }