use super::{block_enum, parse_blocks};
use crate::error::{Error, Result};
use binrw::BinRead;
use serde::Serialize;
use std::io::{Cursor, Read};
block_enum! {
pub enum ExternalBlock {
0 => Utc(UtcData, 5),
1 => Gnss1(GnssData, 46),
2 => Gnss2(GnssData, 46),
3 => ManualGnss(GnssData, 46),
4 => Emlog1(EmlogData, 13),
5 => Emlog2(EmlogData, 13),
6 => Usbl1(UsblData, 49),
7 => Usbl2(UsblData, 49),
8 => Usbl3(UsblData, 49),
9 => Depth(DepthData, 12),
10 => Dvl1GroundSpeed(DvlGroundSpeed, 37),
11 => Dvl1WaterSpeed(DvlWaterSpeed, 33),
12 => SoundVelocity(SoundVelocity, 8),
13 => Dmi(DmiData, 8),
14 => Lbl1(LblData, 41),
15 => Lbl2(LblData, 41),
16 => Lbl3(LblData, 41),
17 => Lbl4(LblData, 41),
18 => EventMarkerA(EventMarker, 9),
19 => EventMarkerB(EventMarker, 9),
20 => EventMarkerC(EventMarker, 9),
21 => Dvl2GroundSpeed(DvlGroundSpeed, 37),
22 => Dvl2WaterSpeed(DvlWaterSpeed, 33),
24 => TurretAngles(TurretAngles, 16),
25 => Vtg1(VtgData, 17),
26 => Vtg2(VtgData, 17),
27 => LogBook(LogBook, 40),
28 => Date(DateData, 8),
}
read_fn();
}
pub fn parse_external_blocks(
bitmask: u32,
cursor: &mut Cursor<&[u8]>,
) -> Result<Vec<ExternalBlock>> {
parse_blocks(bitmask, 29, |bit| {
if bit == 23 {
let mut skip = [0u8; 28];
cursor
.read_exact(&mut skip)
.map_err(|e| Error::InvalidBlock(binrw::Error::Io(e)))?;
return Ok(None);
}
ExternalBlock::read(bit, cursor).map(Some)
})
}
#[derive(Debug, Clone, BinRead, Serialize)]
#[brw(big)]
pub struct UtcData {
pub validity_time: u32,
pub source: u8,
}
#[derive(Debug, Clone, BinRead, Serialize)]
#[brw(big)]
pub struct GnssData {
pub validity_time: i32,
pub gnss_id: u8,
pub gnss_quality: u8,
pub latitude: f64,
pub longitude: f64,
pub altitude: f32,
pub latitude_std_dev: f32,
pub longitude_std_dev: f32,
pub altitude_std_dev: f32,
pub lat_lon_covariance: f32,
pub geoidal_separation: f32,
}
#[derive(Debug, Clone, BinRead, Serialize)]
#[brw(big)]
pub struct EmlogData {
pub validity_time: i32,
pub emlog_id: u8,
pub xv1_speed: f32,
pub xv1_speed_std_dev: f32,
}
#[derive(Debug, Clone, BinRead, Serialize)]
#[brw(big)]
pub struct UsblData {
pub validity_time: i32,
pub usbl_id: u8,
pub beacon_id: [u8; 8],
pub latitude: f64,
pub longitude: f64,
pub altitude: f32,
pub north_std_dev: f32,
pub east_std_dev: f32,
pub lat_lon_covariance: f32,
pub altitude_std_dev: f32,
}
#[derive(Debug, Clone, BinRead, Serialize)]
#[brw(big)]
pub struct DepthData {
pub validity_time: i32,
pub depth: f32,
pub depth_std_dev: f32,
}
#[derive(Debug, Clone, BinRead, Serialize)]
#[brw(big)]
pub struct DvlGroundSpeed {
pub validity_time: i32,
pub dvl_id: u8,
pub xs1_ground_speed: f32,
pub xs2_ground_speed: f32,
pub xs3_ground_speed: f32,
pub speed_of_sound: f32,
pub altitude: f32,
pub xs1_speed_std_dev: f32,
pub xs2_speed_std_dev: f32,
pub xs3_speed_std_dev: f32,
}
#[derive(Debug, Clone, BinRead, Serialize)]
#[brw(big)]
pub struct DvlWaterSpeed {
pub validity_time: i32,
pub dvl_id: u8,
pub xs1_water_speed: f32,
pub xs2_water_speed: f32,
pub xs3_water_speed: f32,
pub speed_of_sound: f32,
pub xs1_speed_std_dev: f32,
pub xs2_speed_std_dev: f32,
pub xs3_speed_std_dev: f32,
}
#[derive(Debug, Clone, BinRead, Serialize)]
#[brw(big)]
pub struct SoundVelocity {
pub validity_time: i32,
pub speed_of_sound: f32,
}
#[derive(Debug, Clone, BinRead, Serialize)]
#[brw(big)]
pub struct DmiData {
pub validity_time: i32,
pub pulse_count: i32,
}
#[derive(Debug, Clone, BinRead, Serialize)]
#[brw(big)]
pub struct LblData {
pub validity_time: i32,
pub rfu: u8,
pub beacon_id: [u8; 8],
pub beacon_latitude: f64,
pub beacon_longitude: f64,
pub beacon_altitude: f32,
pub range: f32,
pub range_std_dev: f32,
}
#[derive(Debug, Clone, BinRead, Serialize)]
#[brw(big)]
pub struct EventMarker {
pub validity_time: i32,
pub event_id: u8,
pub event_count: i32,
}
#[derive(Debug, Clone, BinRead, Serialize)]
#[brw(big)]
pub struct TurretAngles {
pub validity_time: i32,
pub heading: f32,
pub roll: f32,
pub pitch: f32,
}
#[derive(Debug, Clone, BinRead, Serialize)]
#[brw(big)]
pub struct VtgData {
pub validity_time: i32,
pub vtg_id: u8,
pub true_course: f32,
pub magnetic_course: f32,
pub speed_over_ground: f32,
}
#[derive(Debug, Clone, BinRead, Serialize)]
#[brw(big)]
pub struct LogBook {
pub validity_time: i32,
pub identifier: u32,
pub custom_text: [u8; 32],
}
#[derive(Debug, Clone, BinRead, Serialize)]
#[brw(big)]
pub struct DateData {
pub validity_time: i32,
pub day: u8,
pub month: u8,
pub year: u16,
}