use crate::constants;
use serde::{Deserialize, Serialize};
#[derive(Copy, Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
pub struct ATCAPacket<'a> {
pub pkt_id: u8,
pub txsize: u8,
pub opcode: u8,
pub param1: u8,
pub param2: [u8; 2],
pub req_data: &'a [u8],
pub crc16: [u8; 2],
}
impl<'a> ATCAPacket<'_> {
pub fn make_packet(
&mut self,
txsize: Option<u8>,
opcode: Option<u8>,
param1: Option<u8>,
param2: Option<[u8; 2]>,
) -> &mut Self {
match txsize {
None => self.txsize = constants::ATCA_CMD_SIZE_MIN,
Some(t) => self.txsize = t,
}
self.opcode = opcode.unwrap();
self.param1 = param1.unwrap();
match param2 {
None => self.param2 = [0; 2],
Some(t) => self.param2 = t,
}
let packet: [u8; 5] = [
self.txsize,
self.opcode,
self.param1,
self.param2[0],
self.param2[1],
];
let crc_bytes = self.crc(&packet[..], packet.len());
self.crc16[0] = crc_bytes[0];
self.crc16[1] = crc_bytes[1];
return self;
}
pub fn crc(self, src: &[u8], length: usize) -> [u8; 2] {
let polynom: u16 = 0x8005;
let mut crc: u16 = 0x0000;
let mut data_bit;
let mut crc_bit;
let mut d: u8;
for i in 0..length {
d = src[i];
for b in 0..8 {
if (d & 1 << b) == 0 {
data_bit = 0;
} else {
data_bit = 1;
}
crc_bit = crc >> 15 & 0xff;
crc = crc << (1 & 0xffff);
if data_bit != crc_bit {
crc = crc ^ (polynom & 0xffff);
}
}
}
let lsb = crc & 0x00ff;
let msb = crc >> 8 & 0xff;
return [lsb as u8, msb as u8];
}
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
pub struct ATCAPacket_w_data<'a> {
pub pkt_id: u8,
pub txsize: u8,
pub opcode: u8,
pub param1: u8,
pub param2: [u8; 2],
pub req_data: &'a [u8],
pub crc16: [u8; 2],
}
impl<'a> ATCAPacket_w_data<'_> {
pub fn make_packet(
&mut self,
txsize: Option<u8>,
opcode: Option<u8>,
param1: Option<u8>,
param2: Option<[u8; 2]>,
) -> &mut Self {
match txsize {
None => self.txsize = constants::ATCA_CMD_SIZE_MIN,
Some(t) => self.txsize = t,
}
self.opcode = opcode.unwrap();
self.param1 = param1.unwrap();
match param2 {
None => self.param2 = [0; 2],
Some(t) => self.param2 = t,
}
let packet: &[&[u8]] = &[
&[self.txsize],
&[0, self.opcode],
&[0, 0, self.param1],
&[0, 0, 0, self.param2[0]],
&[0, 0, 0, 0, self.param2[1]],
self.req_data,
];
let crc_bytes = self.crc(packet, packet.len());
self.crc16[0] = crc_bytes[0];
self.crc16[1] = crc_bytes[1];
return self;
}
pub fn crc(self, src: &[&[u8]], length: usize) -> [u8; 2] {
let polynom: u16 = 0x8005;
let mut crc: u16 = 0x0000;
let mut data_bit;
let mut crc_bit;
let mut d: u8;
for i in 0..length {
if i == length - 1 {
for i in 0..self.req_data.len() {
d = src[length - 1][i];
for b in 0..8 {
if (d & 1 << b) == 0 {
data_bit = 0;
} else {
data_bit = 1;
}
crc_bit = crc >> 15 & 0xff;
crc = crc << (1 & 0xffff);
if data_bit != crc_bit {
crc = crc ^ (polynom & 0xffff);
}
}
}
} else {
d = src[i][i];
for b in 0..8 {
if (d & 1 << b) == 0 {
data_bit = 0;
} else {
data_bit = 1;
}
crc_bit = crc >> 15 & 0xff;
crc = crc << (1 & 0xffff);
if data_bit != crc_bit {
crc = crc ^ (polynom & 0xffff);
}
}
}
}
let lsb = crc & 0x00ff;
let msb = crc >> 8 & 0xff;
return [lsb as u8, msb as u8];
}
}