use std::fmt::Display;
use zerocopy::{Immutable, IntoBytes, KnownLayout, TryFromBytes, Unaligned};
#[derive(Debug, Clone, Copy, Immutable, TryFromBytes, IntoBytes)]
#[repr(u8)]
pub enum StartOfFrame {
AA = 0xAA,
}
#[derive(Debug, Clone, Copy, Immutable, TryFromBytes, IntoBytes)]
#[repr(u8)]
pub enum Version {
V0 = 0,
}
#[derive(Debug, KnownLayout, Immutable, Unaligned, TryFromBytes, IntoBytes)]
#[repr(C, packed)]
pub struct SdkPacketHeader {
pub sof: StartOfFrame,
pub version: Version,
pub length: u16,
pub seq_num: u32,
pub cmd_id: CommandID,
pub cmd_type: CommandType,
pub sender_type: SendType,
pub reserved: [u8; 6],
pub crc16_h: u16,
pub crc32_d: u32,
}
impl SdkPacketHeader {
pub const SIZE: usize = std::mem::size_of::<Self>();
pub fn new(
data_length: usize,
cmd_id: CommandID,
cmd_type: CommandType,
sender_type: SendType,
) -> Self {
let length = (Self::SIZE + data_length) as u16;
Self {
sof: StartOfFrame::AA,
version: Version::V0,
length,
seq_num: crate::seq::next_seq(),
cmd_id,
cmd_type,
sender_type,
reserved: [0; 6],
crc16_h: 0,
crc32_d: 0,
}
}
pub fn data_len(&self) -> usize {
self.length as usize - Self::SIZE
}
}
#[derive(Debug, Clone, Copy, Immutable, TryFromBytes, IntoBytes)]
#[repr(u16)]
pub enum CommandID {
QueryDeviceType = 0x0000,
ConfigParamInfo = 0x0001,
InquireLidarInfo = 0x0101,
PushLidarInfo = 0x0102,
RequestRebootDevice = 0x0200,
RestoreFactorySettings = 0x0201,
SetGpsTimestamp = 0x0202,
PushLogFile = 0x0300,
LogCollectionConfig = 0x0301,
SyncLogSystemTime = 0x0302,
DebugRawDataCollectionConfig = 0x0303,
RequestStartUpgrade = 0x0400,
TransferFirmwareData = 0x0401,
FirmwareTransferComplete = 0x0402,
GetFirmwareUpgradeStatus = 0x0403,
}
impl Display for CommandID {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::QueryDeviceType => write!(f, "Discovery device type by broadcasting"),
Self::ConfigParamInfo => write!(f, "Parameter information configuration"),
Self::InquireLidarInfo => write!(f, "Inquire LiDAR information"),
Self::PushLidarInfo => write!(f, "Push LiDAR information"),
Self::RequestRebootDevice => write!(f, "Request reboot device"),
Self::RestoreFactorySettings => write!(f, "Restore factory settings"),
Self::SetGpsTimestamp => write!(f, "Set GPS timestamp"),
Self::PushLogFile => write!(f, "Log file push"),
Self::LogCollectionConfig => write!(f, "Log collection configuration"),
Self::SyncLogSystemTime => write!(f, "Log system time synchronization"),
Self::DebugRawDataCollectionConfig => {
write!(f, "Debug raw data collection configuration")
}
Self::RequestStartUpgrade => write!(f, "Request to start upgrade"),
Self::TransferFirmwareData => write!(f, "Firmware data transfer"),
Self::FirmwareTransferComplete => write!(f, "Firmware transfer complete"),
Self::GetFirmwareUpgradeStatus => write!(f, "Get firmware upgrade status"),
}
}
}
impl CommandID {
pub const COUNT: usize = 256;
}
#[derive(Debug, Clone, Copy, KnownLayout, Immutable, TryFromBytes, IntoBytes)]
#[repr(u8)]
pub enum CommandType {
Cmd = 0,
Ack = 1,
}
#[derive(Debug, Clone, Copy, KnownLayout, Immutable, TryFromBytes, IntoBytes)]
#[repr(u8)]
pub enum SendType {
HostSend = 0,
LidarSend = 1,
}
#[derive(Debug, KnownLayout, Immutable, Unaligned, TryFromBytes, IntoBytes)]
#[repr(C, packed)]
pub struct QueryDeviceTypeAck {
pub ret_code: u8,
pub dev_type: LivoxLidarDeviceType,
pub sn: [u8; 16],
pub lidar_ip: [u8; 4],
pub cmd_port: u16,
}
#[derive(Debug, Clone, Copy, Immutable, TryFromBytes, IntoBytes)]
#[repr(u8)]
pub enum LivoxLidarDeviceType {
Hub = 0,
Mid40 = 1,
Tele = 2,
Horizon = 3,
Mid70 = 6,
Avia = 7,
Mid360 = 9,
IndustrialHAP = 10,
HAP = 15,
PA = 16,
}
impl QueryDeviceTypeAck {
#[inline]
pub fn is_valid(&self) -> bool {
self.ret_code == 0
}
}