]>
code.octet-stream.net Git - m17rt/blob - m17core/src/protocol.rs
2 address
::{encode_address
, Address
},
6 pub(crate) const LSF_SYNC
: [i8; 8] = [1, 1, 1, 1, -1, -1, 1, -1];
7 pub(crate) const BERT_SYNC
: [i8; 8] = [-1, 1, -1, -1, 1, 1, 1, 1];
8 pub(crate) const STREAM_SYNC
: [i8; 8] = [-1, -1, -1, -1, 1, 1, -1, 1];
9 pub(crate) const PACKET_SYNC
: [i8; 8] = [1, -1, 1, 1, -1, -1, -1, -1];
10 pub(crate) const PREAMBLE
: [i8; 8] = [1, -1, 1, -1, 1, -1, 1, -1];
11 pub(crate) const END_OF_TRANSMISSION
: [i8; 8] = [1, 1, 1, 1, 1, 1, -1, 1];
13 #[derive(Debug, Clone, PartialEq, Eq, Copy)]
18 #[derive(Debug, Clone, PartialEq, Eq, Copy)]
25 #[derive(Debug, Clone, PartialEq, Eq, Copy)]
26 pub enum EncryptionType
{
33 #[derive(Debug, Clone, PartialEq, Eq)]
41 #[derive(Debug, Clone, PartialEq, Eq, Copy)]
62 pub fn from_proto(buf
: &[u8]) -> Option
<(Self, usize)> {
65 .and_then(|chunk
| chunk
.valid().chars().next())
66 .map(|c
| match c
as u32 {
67 0x00 => (PacketType
::Raw
, 1),
68 0x01 => (PacketType
::Ax25
, 1),
69 0x02 => (PacketType
::Aprs
, 1),
70 0x03 => (PacketType
::SixLowPan
, 1),
71 0x04 => (PacketType
::Ipv4
, 1),
72 0x05 => (PacketType
::Sms
, 1),
73 0x06 => (PacketType
::Winlink
, 1),
74 _
=> (PacketType
::Other(c
), c
.len_utf8()),
78 pub fn as_proto(&self) -> ([u8; 4], usize) {
80 PacketType
::Raw
=> ([0, 0, 0, 0], 1),
81 PacketType
::Ax25
=> ([1, 0, 0, 0], 1),
82 PacketType
::Aprs
=> ([2, 0, 0, 0], 1),
83 PacketType
::SixLowPan
=> ([3, 0, 0, 0], 1),
84 PacketType
::Ipv4
=> ([4, 0, 0, 0], 1),
85 PacketType
::Sms
=> ([5, 0, 0, 0], 1),
86 PacketType
::Winlink
=> ([6, 0, 0, 0], 1),
87 PacketType
::Other(c
) => {
88 let mut buf
= [0u8; 4];
89 let s
= c
.encode_utf8(&mut buf
);
97 #[derive(Debug, Clone, PartialEq, Eq)]
98 pub struct LsfFrame(pub [u8; 30]);
101 pub fn new_voice(source
: &Address
, destination
: &Address
) -> Self {
102 let mut out
= Self([0u8; 30]);
103 out
.set_source(source
);
104 out
.set_destination(destination
);
105 out
.set_mode(Mode
::Stream
);
106 out
.set_data_type(DataType
::Voice
);
107 out
.set_encryption_type(EncryptionType
::None
);
111 pub fn new_packet(source
: &Address
, destination
: &Address
) -> Self {
112 let mut out
= Self([0u8; 30]);
113 out
.set_source(source
);
114 out
.set_destination(destination
);
115 out
.set_mode(Mode
::Packet
);
116 out
.set_data_type(DataType
::Data
);
117 out
.set_encryption_type(EncryptionType
::None
);
121 /// Calculate crc of entire frame. If zero, it is a valid frame.
122 pub fn check_crc(&self) -> u16 {
123 crate::crc
::m17_crc(&self.0)
126 pub fn destination(&self) -> Address
{
127 crate::address
::decode_address((&self.0[0..6]).try_into().unwrap
())
130 pub fn source(&self) -> Address
{
131 crate::address
::decode_address((&self.0[6..12]).try_into().unwrap
())
134 pub fn mode(&self) -> Mode
{
135 if self.lsf_type() & 0x0001 > 0 {
142 pub fn data_type(&self) -> DataType
{
143 match (self.0[12] >> 1) & 0x03 {
144 0b00 => DataType
::Reserved
,
145 0b01 => DataType
::Data
,
146 0b10 => DataType
::Voice
,
147 0b11 => DataType
::VoiceAndData
,
152 pub fn encryption_type(&self) -> EncryptionType
{
153 match (self.lsf_type() >> 3) & 0x0003 {
154 0b00 => EncryptionType
::None
,
155 0b01 => EncryptionType
::Scrambler
,
156 0b10 => EncryptionType
::Aes
,
157 0b11 => EncryptionType
::Other
,
162 // TODO: encryption sub-type
164 pub fn channel_access_number(&self) -> u8 {
165 ((self.lsf_type() >> 7) & 0x000f) as u8
168 pub fn meta(&self) -> [u8; 14] {
169 self.0[14..28].try_into().unwrap
()
172 pub fn set_destination(&mut self, destination
: &Address
) {
173 self.0[0..6].copy_from_slice(&encode_address(destination
));
174 self.recalculate_crc();
177 pub fn set_source(&mut self, source
: &Address
) {
178 self.0[6..12].copy_from_slice(&encode_address(source
));
179 self.recalculate_crc();
182 pub fn set_mode(&mut self, mode
: Mode
) {
183 let existing_type
= self.lsf_type();
184 let new_type
= (existing_type
& !0x0001) | if mode
== Mode
::Stream
{ 1 } else { 0 };
185 self.0[12..14].copy_from_slice(&new_type
.to_be_bytes());
186 self.recalculate_crc();
189 pub fn set_data_type(&mut self, data_type
: DataType
) {
190 let type_part
= match data_type
{
191 DataType
::Reserved
=> 0b00 << 1,
192 DataType
::Data
=> 0b01 << 1,
193 DataType
::Voice
=> 0b10 << 1,
194 DataType
::VoiceAndData
=> 0b11 << 1,
196 let existing_type
= self.lsf_type();
197 let new_type
= (existing_type
& !0x0006) | type_part
;
198 self.0[12..14].copy_from_slice(&new_type
.to_be_bytes());
199 self.recalculate_crc();
202 pub fn set_encryption_type(&mut self, encryption_type
: EncryptionType
) {
203 let type_part
= match encryption_type
{
204 EncryptionType
::None
=> 0b00 << 3,
205 EncryptionType
::Scrambler
=> 0b01 << 3,
206 EncryptionType
::Aes
=> 0b10 << 3,
207 EncryptionType
::Other
=> 0b11 << 3,
209 let existing_type
= self.lsf_type();
210 let new_type
= (existing_type
& !0x0018) | type_part
;
211 self.0[12..14].copy_from_slice(&new_type
.to_be_bytes());
212 self.recalculate_crc();
215 pub fn set_channel_access_number(&mut self, number
: u8) {
216 let mut bits
= BitsMut
::new(&mut self.0);
217 bits
.set_bit(12 * 8 + 5, (number
>> 3) & 1);
218 bits
.set_bit(12 * 8 + 6, (number
>> 2) & 1);
219 bits
.set_bit(12 * 8 + 7, (number
>> 1) & 1);
220 bits
.set_bit(13 * 8, number
& 1);
221 self.recalculate_crc();
224 fn recalculate_crc(&mut self) {
225 let new_crc
= crate::crc
::m17_crc(&self.0[0..28]);
226 self.0[28..30].copy_from_slice(&new_crc
.to_be_bytes());
227 debug_assert_eq
!(self.check_crc(), 0);
230 fn lsf_type(&self) -> u16 {
231 u16::from_be_bytes([self.0[12], self.0[13]])
235 #[derive(Debug, Clone, PartialEq, Eq, Default)]
236 pub struct StreamFrame
{
237 /// Which LICH segment is given in this frame, from 0 to 5 inclusive
239 /// Decoded LICH segment
240 pub lich_part
: [u8; 5],
241 /// Which frame in the transmission this is, starting from 0
242 pub frame_number
: u16,
243 /// Is this the last frame in the transmission?
244 pub end_of_stream
: bool
,
245 /// Raw application data in this frame
246 pub stream_data
: [u8; 16],
249 #[derive(Debug, Clone, PartialEq, Eq)]
250 pub struct PacketFrame
{
251 /// Application packet payload (chunk)
252 pub payload
: [u8; 25],
254 /// Frame counter, which provides different information depending on whether this is the last frame or not.
255 pub counter
: PacketFrameCounter
,
258 #[derive(Debug, Clone, PartialEq, Eq)]
259 pub enum PacketFrameCounter
{
260 /// Any packet frame that comes after the LSF and is not the final frame.
262 /// Which frame this is in the superframe, from 0 to 31 inclusive.
264 /// If a 33rd frame exists (index 32), it will be a `FinalFrame` instead.
266 /// All 25 bytes of of `payload` are filled and valid.
269 /// The final frame in the packet superframe.
271 /// The number of bytes in `payload` that are filled.
276 pub struct LichCollection([Option
<[u8; 5]>; 6]);
278 impl LichCollection
{
279 pub fn new() -> Self {
283 pub fn valid_segments(&self) -> usize {
284 self.0.iter
().filter
(|s
| s
.is
_some
()).count()
287 pub fn set_segment(&mut self, counter
: u8, part
: [u8; 5]) {
288 self.0[counter
as usize] = Some(part
);
291 pub fn try_assemble(&self) -> Option
<[u8; 30]> {
292 let mut out
= [0u8; 30];
293 for (i
, segment
) in self.0.iter
().enumerate() {
294 let Some(segment
) = segment
else {
297 for (j
, seg_val
) in segment
.iter
().enumerate() {
298 out
[i
* 5 + j
] = *seg_val
;
305 impl Default
for LichCollection
{
306 fn default() -> Self {
317 let mut frame
= LsfFrame([0u8; 30]);
318 frame
.set_channel_access_number(11);
319 assert_eq
!(frame
.channel_access_number(), 11);