use crate::{Error, utils::Utils};
#[derive(Debug, Clone, PartialEq, Default)]
pub struct SBASEphemeris {
pub sbas_prn: u8,
pub toe: u16,
pub tow: i32,
pub clock_offset: f64,
pub clock_drift: f64,
pub x_km: f64,
pub vel_x_km: f64,
pub acc_x_km: f64,
pub y_km: f64,
pub vel_y_km: f64,
pub acc_y_km: f64,
pub z_km: f64,
pub vel_z_km: f64,
pub acc_z_km: f64,
pub uint1: u8,
pub ura: u8,
pub iodn: u8,
}
impl SBASEphemeris {
pub(crate) const fn encoding_size() -> usize {
98
}
pub(crate) fn encode(&self, big_endian: bool, buf: &mut [u8]) -> Result<usize, Error> {
let size = Self::encoding_size();
if buf.len() < size {
return Err(Error::NotEnoughBytes);
}
buf[0] = self.sbas_prn;
let toe = if big_endian {
self.toe.to_be_bytes()
} else {
self.toe.to_le_bytes()
};
buf[1..3].copy_from_slice(&toe);
let tow = if big_endian {
self.tow.to_be_bytes()
} else {
self.tow.to_le_bytes()
};
buf[3..7].copy_from_slice(&tow);
let clock_offset = if big_endian {
self.clock_offset.to_be_bytes()
} else {
self.clock_offset.to_le_bytes()
};
buf[7..15].copy_from_slice(&clock_offset);
let clock_drift = if big_endian {
self.clock_drift.to_be_bytes()
} else {
self.clock_drift.to_le_bytes()
};
buf[15..23].copy_from_slice(&clock_drift);
let x_km = if big_endian {
self.x_km.to_be_bytes()
} else {
self.x_km.to_le_bytes()
};
buf[23..31].copy_from_slice(&x_km);
let vel_x_km = if big_endian {
self.vel_x_km.to_be_bytes()
} else {
self.vel_x_km.to_le_bytes()
};
buf[31..39].copy_from_slice(&vel_x_km);
let acc_x_km = if big_endian {
self.acc_x_km.to_be_bytes()
} else {
self.acc_x_km.to_le_bytes()
};
buf[39..47].copy_from_slice(&acc_x_km);
let y_km = if big_endian {
self.y_km.to_be_bytes()
} else {
self.y_km.to_le_bytes()
};
buf[47..55].copy_from_slice(&y_km);
let vel_y_km = if big_endian {
self.vel_y_km.to_be_bytes()
} else {
self.vel_y_km.to_le_bytes()
};
buf[55..63].copy_from_slice(&vel_y_km);
let acc_y_km = if big_endian {
self.acc_y_km.to_be_bytes()
} else {
self.acc_y_km.to_le_bytes()
};
buf[63..71].copy_from_slice(&acc_y_km);
let z_km = if big_endian {
self.z_km.to_be_bytes()
} else {
self.z_km.to_le_bytes()
};
buf[71..79].copy_from_slice(&z_km);
let vel_z_km = if big_endian {
self.vel_z_km.to_be_bytes()
} else {
self.vel_z_km.to_le_bytes()
};
buf[79..87].copy_from_slice(&vel_z_km);
let acc_z_km = if big_endian {
self.acc_z_km.to_be_bytes()
} else {
self.acc_z_km.to_le_bytes()
};
buf[87..95].copy_from_slice(&acc_z_km);
buf[95] = self.uint1;
buf[96] = self.ura;
buf[97] = self.iodn;
Ok(Self::encoding_size())
}
pub(crate) fn decode(big_endian: bool, buf: &[u8]) -> Result<Self, Error> {
if buf.len() < Self::encoding_size() {
return Err(Error::NotEnoughBytes);
}
let sbas_prn = buf[0];
let toe = Utils::decode_u16(big_endian, &buf[1..3])?;
let tow = Utils::decode_i32(big_endian, &buf[3..7])?;
let clock_offset = Utils::decode_f64(big_endian, &buf[7..15])?;
let clock_drift = Utils::decode_f64(big_endian, &buf[15..23])?;
let x_km = Utils::decode_f64(big_endian, &buf[23..31])?;
let vel_x_km = Utils::decode_f64(big_endian, &buf[31..39])?;
let acc_x_km = Utils::decode_f64(big_endian, &buf[39..47])?;
let y_km = Utils::decode_f64(big_endian, &buf[47..55])?;
let vel_y_km = Utils::decode_f64(big_endian, &buf[55..63])?;
let acc_y_km = Utils::decode_f64(big_endian, &buf[63..71])?;
let z_km = Utils::decode_f64(big_endian, &buf[71..79])?;
let vel_z_km = Utils::decode_f64(big_endian, &buf[79..87])?;
let acc_z_km = Utils::decode_f64(big_endian, &buf[87..95])?;
let uint1 = buf[95];
let ura = buf[96];
let iodn = buf[97];
Ok(Self {
sbas_prn,
toe,
tow,
clock_offset,
clock_drift,
x_km,
vel_x_km,
acc_x_km,
y_km,
vel_y_km,
acc_y_km,
z_km,
vel_z_km,
acc_z_km,
uint1,
ura,
iodn,
})
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn eph_x00_x03_error() {
let buf = [0; 64];
assert!(SBASEphemeris::decode(true, &buf).is_err());
}
#[test]
fn sbas_ephemeris() {
for big_endian in [true, false] {
let buf = [0; 100];
let eph = SBASEphemeris::decode(big_endian, &buf).unwrap();
let mut target = [0; 64];
assert!(eph.encode(big_endian, &mut target).is_err());
let mut target = [0; 100];
let size = eph.encode(big_endian, &mut target).unwrap();
assert_eq!(size, 98);
assert_eq!(buf, target);
let eph = SBASEphemeris {
sbas_prn: 10,
toe: 11,
tow: 12,
clock_drift: 0.1,
clock_offset: 0.2,
x_km: 1.4,
vel_x_km: 1.5,
acc_x_km: 1.6,
y_km: 2.4,
vel_y_km: 2.5,
acc_y_km: 2.6,
z_km: 3.1,
vel_z_km: 3.2,
acc_z_km: 3.3,
uint1: 4,
ura: 5,
iodn: 6,
};
let mut target = [0; 100];
eph.encode(big_endian, &mut target).unwrap();
let decoded = SBASEphemeris::decode(big_endian, &target).unwrap();
assert_eq!(eph, decoded);
}
}
}