pub mod common;
pub mod display;
pub mod sensor;
use num_enum::IntoPrimitive;
use num_enum::TryFromPrimitive;
use std::convert::TryFrom;
use byteorder::{ByteOrder, LittleEndian};
use crate::base::system::{*};
use crate::communication::extractor::Extractor;
#[derive(Clone, Copy, Debug, Eq, PartialEq, IntoPrimitive, TryFromPrimitive)]
#[repr(u8)]
pub enum DataType {
#[num_enum(default)]
None = 0x00,
Ping = 0x01,
Ack = 0x02,
Error = 0x03,
Request = 0x04,
Message = 0x05,
Address = 0x06,
Information = 0x07,
Update = 0x08,
UpdateLocation = 0x09,
Encrypt = 0x0A,
SystemCount = 0x0B,
SystemInformation = 0x0C,
Registration = 0x0D,
Administrator = 0x0E,
Monitor = 0x0F,
Control = 0x10,
Command = 0x11,
Pairing = 0x12,
Rssi = 0x13,
TimeSync = 0x14,
TransmissionPower = 0x15,
Configuration = 0x16,
Echo = 0x17,
Battle = 0x1F,
LightManual = 0x20,
LightMode = 0x21,
LightEvent = 0x22,
LightDefault = 0x23,
RawMotion = 0x30,
RawFlow = 0x31,
State = 0x40,
Attitude = 0x41,
Position = 0x42,
Altitude = 0x43,
Motion = 0x44,
Range = 0x45,
Count = 0x50,
Bias = 0x51,
Trim = 0x52,
Weight = 0x53,
LostConnection = 0x54,
MagnetometerOffset = 0x55,
Motor = 0x60,
MotorSingle = 0x61,
Buzzer = 0x62,
Vibrator = 0x63,
Button = 0x70,
Joystick = 0x71,
DisplayClear = 0x80,
DisplayInvert = 0x81,
DisplayDrawPoint = 0x82,
DisplayDrawLine = 0x83,
DisplayDrawRect = 0x84,
DisplayDrawCircle = 0x85,
DisplayDrawString = 0x86,
DisplayDrawStringAlign = 0x87,
DisplayDrawImage = 0x88,
CardClassify = 0x90,
CardRange = 0x91,
CardRaw = 0x92,
CardColor = 0x93,
CardList = 0x94,
CardFunctionList = 0x95,
InformationAssembledForController = 0xA0,
InformationAssembledForEntry = 0xA1,
InformationAssembledForByBlocks = 0xA2,
NavigationTarget = 0xD0,
NavigationLocation = 0xD1,
NavigationMonitor = 0xD2,
NavigationHeading = 0xD3,
NavigationCounter = 0xD4,
NavigationSatellite = 0xD5,
NavigationLocationAdjust = 0xD6,
NavigationTargetEcef = 0xD8,
NavigationLocationEcef = 0xD9,
GpsRtkNavigationState = 0xDA,
GpsRtkExtendedRawMeasurementData = 0xDB,
}
impl DataType {
pub fn from_u8(data: u8) -> DataType {
match DataType::try_from( data ) {
Ok(data_type) => { data_type },
_ => { DataType::None },
}
}
}
#[repr(u8)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, TryFromPrimitive)]
pub enum CommandType {
#[num_enum(default)]
None = 0x00,
Stop = 0x01,
ModeControlFlight = 0x02,
Headless = 0x03,
ControlSpeed = 0x04,
ClearBias = 0x05,
ClearTrim = 0x06,
FlightEvent = 0x07,
SetDefault = 0x08,
Backlight = 0x09,
ModeController = 0x0A,
Link = 0x0B,
ClearMagnetometer = 0x0C,
ClearCounter = 0xA0,
JumpToBootloader = 0xA1,
JumpToApplication = 0xA2,
NavigationTargetClear = 0xE0,
NavigationStart = 0xE1,
NavigationPause = 0xE2,
NavigationRestart = 0xE3,
NavigationStop = 0xE4,
NavigationNext = 0xE5,
NavigationReturnToHome = 0xE6,
GpsRtkBase = 0xEA,
GpsRtkRover = 0xEB,
TestLock = 0xF0,
}
#[derive(Debug)]
pub enum Data {
None,
Header {header: Header},
Motion {motion: sensor::Motion},
Information {information: Information},
}
pub trait Serializable
{
fn size() -> usize;
fn to_vec(&self) -> Vec<u8>;
}
#[derive(Debug)]
pub struct Header {
pub data_type: DataType,
pub length: u8,
pub from: DeviceType,
pub to: DeviceType,
}
impl Header {
pub fn new() -> Header{
Header {
data_type: DataType::None,
length: 0,
from: DeviceType::None,
to: DeviceType::None,
}
}
pub fn parse(header: &mut Header, vec_data: &Vec<u8>) -> bool {
if vec_data.len() != Header::size() {
return false;
}
header.data_type = DataType::from_u8(vec_data[0]);
header.length = vec_data[1];
header.from = DeviceType::from_u8(vec_data[2]);
header.to = DeviceType::from_u8(vec_data[3]);
true
}
pub fn from_vec(vec_data: &Vec<u8>) -> Header {
let mut data = Header::new();
Header::parse(&mut data, vec_data);
data
}
}
impl Serializable for Header {
fn size() -> usize { 4 }
fn to_vec(&self) -> Vec<u8> {
let mut vec_data : Vec<u8> = Vec::new();
vec_data.push(self.data_type.into());
vec_data.push(self.length);
vec_data.push(self.from.into());
vec_data.push(self.to.into());
vec_data
}
}
#[derive(Debug)]
pub struct Information {
mode_update: ModeUpdate,
model_number: ModelNumber,
version: Version,
year: u16,
month: u8,
day: u8,
}
impl Information {
pub fn new() -> Information{
Information {
mode_update: ModeUpdate::Ready,
model_number: ModelNumber::None,
version: Version{ major:21, minor:1, build:1 },
year: 2021,
month: 1,
day: 1,
}
}
pub fn parse(information: &mut Information, vec_data: &Vec<u8>) -> bool {
if vec_data.len() != Information::size() {
return false;
}
let mut ext: Extractor = Extractor::new(vec_data);
information.mode_update = ModeUpdate::from_u8(ext.get_u8());
information.model_number = ModelNumber::from_u32(ext.get_u32());
information.version = Version::from_u32(ext.get_u32());
information.year = ext.get_u16();
information.month = ext.get_u8();
information.day = ext.get_u8();
true
}
pub fn from_vec(vec_data: &Vec<u8>) -> Information {
let mut data = Information::new();
Information::parse(&mut data, vec_data);
data
}
}
impl Serializable for Information {
fn size() -> usize { 13 }
fn to_vec(&self) -> Vec<u8> {
let mut vec_data : Vec<u8> = Vec::new();
let mut year_array = [0; 2];
LittleEndian::write_u16(&mut year_array, self.year);
vec_data.push(self.mode_update.into());
vec_data.extend_from_slice(&self.model_number.to_array());
vec_data.extend_from_slice(&self.version.to_array());
vec_data.extend_from_slice(&year_array);
vec_data.push(self.month);
vec_data.push(self.day);
vec_data
}
}