1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
//! BINEX Stream representation
use crate::prelude::{ClosedSourceMeta, Message, Meta};
/// [Message] [Provider]
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum Provider {
/// JPL for internal needs or prototyping.
JPL,
/// IGS
IGS,
/// CU Boulder for internal needs or prototyping.
ColoradoUnivBoulder,
/// NRCan for internal needs or prototyping.
NRCan,
/// UCAR COSMIC <https://www.cosmic.ucar.edu>
UCAR,
/// GPS Solutions Inc.
GPSSolutions,
/// Astech Precision Products
Ashtech,
/// Topcon Positioning Systems
Topcon,
}
impl Provider {
/// Identify potential closed source [Provider]
/// from parsed MID (u32)
pub(crate) fn match_any(mid: u32) -> Option<Self> {
if (0x80..=0x87).contains(&mid) {
Some(Self::UCAR)
} else if (0x88..=0xa7).contains(&mid) {
Some(Self::Ashtech)
} else if (0xa8..=0xaf).contains(&mid) {
Some(Self::Topcon)
} else if (0xb0..=0xb3).contains(&mid) {
Some(Self::GPSSolutions)
} else if (0xb4..=0xb7).contains(&mid) {
Some(Self::NRCan)
} else if (0xb8..=0xbf).contains(&mid) {
Some(Self::JPL)
} else if (0xc0..=0xc3).contains(&mid) {
Some(Self::ColoradoUnivBoulder)
} else {
None
}
}
}
/// Closed source frame that we can encode but not interprate.
/// This particular [StreamElement] can be either a part of a continuous serie or self sustainable.
pub struct ClosedSourceElement<'a> {
/// [ClosedSourceMeta]
pub closed_meta: ClosedSourceMeta,
/// Raw data starting at first byte of undisclosed payload.
pub raw: &'a [u8],
}
impl<'a> ClosedSourceElement<'a> {
/// Interprate this [ClosedSourceElement] using custom undisclosed method.
pub fn interprate(&self, f: &dyn Fn(&[u8])) {
f(&self.raw[..self.closed_meta.size])
}
/// Returns reference to raw data "as is", since interpration is not possible
pub fn raw(&self) -> &'a [u8] {
&self.raw[..self.closed_meta.size]
}
}
/// [StreamElement] represents one element of a continuous BINEX stream.
pub enum StreamElement<'a> {
/// Open Source [Message] we can fully decode & interprate
OpenSource(Message),
/// One non disclosed [ClosedSourceElement] that may be part of a continuous serie of elements.
/// Each chunk of the serie is internally limited to 4096 bytes.
/// While we can encode and decode this serie, we cannot interprate it.
ClosedSource(ClosedSourceElement<'a>),
}
impl<'a> From<Message> for StreamElement<'a> {
fn from(msg: Message) -> Self {
Self::OpenSource(msg)
}
}
impl<'a> StreamElement<'a> {
/// Creates a new open source [Message] ready to be encoded
pub fn new_open_source(msg: Message) -> Self {
Self::OpenSource(msg)
}
/// Creates a new self sustained closed source [StreamElement] provided by desired [Provider].
/// ## Inputs
/// - meta: [Meta] data of this prototype
/// - provider: specific [Provider]
/// - mid: message ID
/// - mlen: total payload length (bytes)
/// - raw: chunk we can encode, decode but not fully interprate
/// - size: size of this chunk
pub fn new_prototype(
open_meta: Meta,
provider: Provider,
mid: u32,
mlen: usize,
raw: &'a [u8],
size: usize,
) -> Self {
Self::ClosedSource(ClosedSourceElement {
raw,
closed_meta: ClosedSourceMeta {
mid,
mlen,
open_meta,
provider,
offset: 0,
size,
},
})
}
/// Add one closed source [StreamElement]s provided by desired [Provider::JPL].
/// While we can encode this into a BINEX stream, only this organization can fully interprate the resulting stream.
/// ## Inputs
/// - meta: [Meta] of this message prototype
/// - mid: message ID
/// - mlen: total payload length (bytes)
/// - raw: content we can encode, decode but not interprate
/// - total: total size of the closed source Message (bytewise).
/// It's either equal to [Meta::mlen] if this prototype if self sustainable,
/// or larger, in case this prototype is only one element of a serie.
pub fn jpl_prototype(meta: Meta, mid: u32, mlen: usize, raw: &'a [u8], size: usize) -> Self {
Self::new_prototype(meta, Provider::JPL, mid, mlen, raw, size)
}
/// Add one closed source [StreamElement]s provided by desired [Provider::JPL].
/// While we can encode this into a BINEX stream, only this organization can fully interprate the resulting stream.
/// ## Inputs
/// - meta: [Meta] of this message prototype
/// - raw: content we can encode, decode but not interprate
/// - total: total size of the closed source Message (bytewise).
/// It's either equal to [Meta::mlen] if this prototype if self sustainable,
/// or larger, in case this prototype is only one element of a serie.
pub fn igs_prototype(meta: Meta, mid: u32, mlen: usize, raw: &'a [u8], size: usize) -> Self {
Self::new_prototype(meta, Provider::IGS, mid, mlen, raw, size)
}
/// Add one closed source [StreamElement]s provided by desired [Provider::ColoradoUnivBoulder].
/// While we can encode this into a BINEX stream, only this organization can fully interprate the resulting stream.
/// ## Inputs
/// - meta: [Meta] of this message prototype
/// - mid: message ID
/// - mlen: total payload length (bytes)
/// - raw: content we can encode, decode but not interprate
/// - total: total size of the closed source Message (bytewise).
/// It's either equal to [Meta::mlen] if this prototype if self sustainable,
/// or larger, in case this prototype is only one element of a serie.
pub fn cuboulder_prototype(
meta: Meta,
mid: u32,
mlen: usize,
raw: &'a [u8],
size: usize,
) -> Self {
Self::new_prototype(meta, Provider::ColoradoUnivBoulder, mid, mlen, raw, size)
}
/// Add one closed source [StreamElement]s provided by desired [Provider::NRCan].
/// While we can encode this into a BINEX stream, only this organization can fully interprate the resulting stream.
/// ## Inputs
/// - meta: [Meta] of this message prototype
/// - mid: message ID
/// - mlen: total payload length (bytes)
/// - raw: content we can encode, decode but not interprate
/// - total: total size of the closed source Message (bytewise).
/// It's either equal to [Meta::mlen] if this prototype if self sustainable,
/// or larger, in case this prototype is only one element of a serie.
pub fn nrcan_prototype(meta: Meta, mid: u32, mlen: usize, raw: &'a [u8], size: usize) -> Self {
Self::new_prototype(meta, Provider::NRCan, mid, mlen, raw, size)
}
/// Add one closed source [StreamElement]s provided by desired [Provider::UCAR].
/// While we can encode this into a BINEX stream, only this organization can fully interprate the resulting stream.
/// ## Inputs
/// - meta: [Meta] of this message prototype
/// - mid: message ID
/// - mlen: total payload length (bytes)
/// - raw: content we can encode, decode but not interprate
/// - total: total size of the closed source Message (bytewise).
/// It's either equal to [Meta::mlen] if this prototype if self sustainable,
/// or larger, in case this prototype is only one element of a serie.
pub fn ucar_prototype(meta: Meta, mid: u32, mlen: usize, raw: &'a [u8], size: usize) -> Self {
Self::new_prototype(meta, Provider::UCAR, mid, mlen, raw, size)
}
}