]>
code.octet-stream.net Git - m17rt/blob - m17core/src/protocol.rs
1 use crate::address
::Address
;
3 pub(crate) const LSF_SYNC
: [i8; 8] = [1, 1, 1, 1, -1, -1, 1, -1];
4 pub(crate) const BERT_SYNC
: [i8; 8] = [-1, 1, -1, -1, 1, 1, 1, 1];
5 pub(crate) const STREAM_SYNC
: [i8; 8] = [-1, -1, -1, -1, 1, 1, -1, 1];
6 pub(crate) const PACKET_SYNC
: [i8; 8] = [1, -1, 1, 1, -1, -1, -1, -1];
8 #[derive(Debug, Clone, PartialEq, Eq)]
13 #[derive(Debug, Clone, PartialEq, Eq)]
20 #[derive(Debug, Clone, PartialEq, Eq)]
21 pub enum EncryptionType
{
28 #[derive(Debug, Clone, PartialEq, Eq)]
36 #[derive(Debug, Clone, PartialEq, Eq)]
57 pub fn from_proto(buf
: &[u8]) -> Option
<(Self, usize)> {
60 .and_then(|chunk
| chunk
.valid().chars().next())
61 .map(|c
| match c
as u32 {
62 0x00 => (PacketType
::Raw
, 1),
63 0x01 => (PacketType
::Ax25
, 1),
64 0x02 => (PacketType
::Aprs
, 1),
65 0x03 => (PacketType
::SixLowPan
, 1),
66 0x04 => (PacketType
::Ipv4
, 1),
67 0x05 => (PacketType
::Sms
, 1),
68 0x06 => (PacketType
::Winlink
, 1),
69 _
=> (PacketType
::Other(c
), c
.len_utf8()),
73 pub fn as_proto(&self) -> ([u8; 4], usize) {
75 PacketType
::Raw
=> ([0, 0, 0, 0], 1),
76 PacketType
::Ax25
=> ([1, 0, 0, 0], 1),
77 PacketType
::Aprs
=> ([2, 0, 0, 0], 1),
78 PacketType
::SixLowPan
=> ([3, 0, 0, 0], 1),
79 PacketType
::Ipv4
=> ([4, 0, 0, 0], 1),
80 PacketType
::Sms
=> ([5, 0, 0, 0], 1),
81 PacketType
::Winlink
=> ([6, 0, 0, 0], 1),
82 PacketType
::Other(c
) => {
83 let mut buf
= [0u8; 4];
84 let s
= c
.encode_utf8(&mut buf
);
92 #[derive(Debug, Clone, PartialEq, Eq)]
93 pub struct LsfFrame(pub [u8; 30]);
96 pub fn crc(&self) -> u16 {
97 crate::crc
::m17_crc(&self.0)
100 pub fn destination(&self) -> Address
{
101 crate::address
::decode_address((&self.0[0..6]).try_into().unwrap
())
104 pub fn source(&self) -> Address
{
105 crate::address
::decode_address((&self.0[6..12]).try_into().unwrap
())
108 pub fn mode(&self) -> Mode
{
109 if self.0[12] & 0x01 > 0 {
116 pub fn data_type(&self) -> DataType
{
117 match (self.0[12] >> 1) & 0x03 {
118 0b00 => DataType
::Reserved
,
119 0b01 => DataType
::Data
,
120 0b10 => DataType
::Voice
,
121 0b11 => DataType
::VoiceAndData
,
126 pub fn encryption_type(&self) -> EncryptionType
{
127 match (self.0[12] >> 3) & 0x03 {
128 0b00 => EncryptionType
::None
,
129 0b01 => EncryptionType
::Scrambler
,
130 0b10 => EncryptionType
::Aes
,
131 0b11 => EncryptionType
::Other
,
136 pub fn channel_access_number(&self) -> u8 {
137 (self.0[12] >> 7) & 0x0f
140 pub fn meta(&self) -> [u8; 14] {
141 self.0[14..28].try_into().unwrap
()
145 #[derive(Debug, Clone, PartialEq, Eq)]
146 pub struct StreamFrame
{
147 /// Which LICH segment is given in this frame, from 0 to 5 inclusive
149 /// Decoded LICH segment
150 pub lich_part
: [u8; 5],
151 /// Which frame in the transmission this is, starting from 0
152 pub frame_number
: u16,
153 /// Is this the last frame in the transmission?
154 pub end_of_stream
: bool
,
155 /// Raw application data in this frame
156 pub stream_data
: [u8; 16],
159 pub struct LichCollection([Option
<[u8; 5]>; 6]);
161 impl LichCollection
{
162 pub fn new() -> Self {
166 pub fn valid_segments(&self) -> usize {
167 self.0.iter
().filter
(|s
| s
.is
_some
()).count()
170 pub fn set_segment(&mut self, counter
: u8, part
: [u8; 5]) {
171 self.0[counter
as usize] = Some(part
);
174 pub fn try_assemble(&self) -> Option
<[u8; 30]> {
175 let mut out
= [0u8; 30];
176 for (i
, segment
) in self.0.iter
().enumerate() {
177 let Some(segment
) = segment
else {
180 for (j
, seg_val
) in segment
.iter
().enumerate() {
181 out
[i
* 5 + j
] = *seg_val
;
188 impl Default
for LichCollection
{
189 fn default() -> Self {