1pub mod cfg_val;
2pub mod packets;
3mod types;
4
5use crate::error::MemWriterError;
6pub use packets::*;
7pub use types::*;
8
9pub trait UbxPacketMeta {
11 const CLASS: u8;
12 const ID: u8;
13 const FIXED_PAYLOAD_LEN: Option<u16>;
14 const MAX_PAYLOAD_LEN: u16;
15}
16
17pub(crate) const SYNC_CHAR_1: u8 = 0xb5;
18pub(crate) const SYNC_CHAR_2: u8 = 0x62;
19pub(crate) const RTCM_SYNC_CHAR: u8 = 0xd3;
20
21pub(crate) fn ubx_checksum(data: &[u8]) -> (u8, u8) {
26 let mut ck_a = 0_u8;
27 let mut ck_b = 0_u8;
28 for byte in data {
29 ck_a = ck_a.overflowing_add(*byte).0;
30 ck_b = ck_b.overflowing_add(ck_a).0;
31 }
32 (ck_a, ck_b)
33}
34
35#[derive(Default)]
37struct UbxChecksumCalc {
38 ck_a: u8,
39 ck_b: u8,
40}
41
42impl UbxChecksumCalc {
43 fn update(&mut self, chunk: &[u8]) {
44 for byte in chunk {
45 self.ck_a = self.ck_a.overflowing_add(*byte).0;
46 self.ck_b = self.ck_b.overflowing_add(self.ck_a).0;
47 }
48 }
49 fn result(self) -> (u8, u8) {
50 (self.ck_a, self.ck_b)
51 }
52}
53
54pub trait MemWriter {
57 type Error;
58 fn reserve_allocate(&mut self, len: usize) -> Result<(), MemWriterError<Self::Error>>;
60 fn write(&mut self, buf: &[u8]) -> Result<(), MemWriterError<Self::Error>>;
61}
62
63#[cfg(feature = "std")]
64impl MemWriter for Vec<u8> {
65 type Error = std::io::Error;
66
67 fn reserve_allocate(&mut self, len: usize) -> Result<(), MemWriterError<Self::Error>> {
68 self.reserve(len);
69 Ok(())
70 }
71 fn write(&mut self, buf: &[u8]) -> Result<(), MemWriterError<Self::Error>> {
72 let ret = <dyn std::io::Write>::write(self, buf).map_err(MemWriterError::Custom)?;
73 if ret == buf.len() {
74 Ok(())
75 } else {
76 Err(MemWriterError::NotEnoughMem)
77 }
78 }
79}
80
81pub trait UbxPacketCreator {
82 fn create_packet<T: MemWriter>(self, out: &mut T) -> Result<(), MemWriterError<T::Error>>;
84}
85
86#[derive(Debug, Clone, Copy)]
88#[cfg_attr(feature = "serde", derive(serde::Serialize))]
89pub struct UbxUnknownPacketRef<'a> {
90 pub payload: &'a [u8],
91 pub class: u8,
92 pub msg_id: u8,
93}
94
95#[derive(Debug, Clone)]
96pub struct UbxUnknownPacketOwned<const MAX_PAYLOAD_LEN: usize> {
97 pub payload: [u8; MAX_PAYLOAD_LEN],
98 pub payload_len: usize,
99 pub class: u8,
100 pub msg_id: u8,
101}
102
103pub struct UbxPacketRequest {
105 req_class: u8,
106 req_id: u8,
107}
108
109impl UbxPacketRequest {
110 pub const PACKET_LEN: usize = 8;
111
112 #[inline]
113 pub fn request_for<T: UbxPacketMeta>() -> Self {
114 Self {
115 req_class: T::CLASS,
116 req_id: T::ID,
117 }
118 }
119 #[inline]
120 pub fn request_for_unknown(req_class: u8, req_id: u8) -> Self {
121 Self { req_class, req_id }
122 }
123
124 #[inline]
125 pub fn into_packet_bytes(self) -> [u8; Self::PACKET_LEN] {
126 let mut ret = [
127 SYNC_CHAR_1,
128 SYNC_CHAR_2,
129 self.req_class,
130 self.req_id,
131 0,
132 0,
133 0,
134 0,
135 ];
136 let (ck_a, ck_b) = ubx_checksum(&ret[2..6]);
137 ret[6] = ck_a;
138 ret[7] = ck_b;
139 ret
140 }
141}