]>
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     // TODO: encryption sub-type 
 138     pub fn channel_access_number(&self) -> u8 { 
 139         (self.0[12] >> 7) & 0x0f 
 142     pub fn meta(&self) -> [u8; 14] { 
 143         self.0[14..28].try_into().unwrap
() 
 147 #[derive(Debug, Clone, PartialEq, Eq)] 
 148 pub struct StreamFrame 
{ 
 149     /// Which LICH segment is given in this frame, from 0 to 5 inclusive 
 151     /// Decoded LICH segment 
 152     pub lich_part
: [u8; 5], 
 153     /// Which frame in the transmission this is, starting from 0 
 154     pub frame_number
: u16, 
 155     /// Is this the last frame in the transmission? 
 156     pub end_of_stream
: bool
, 
 157     /// Raw application data in this frame 
 158     pub stream_data
: [u8; 16], 
 161 #[derive(Debug, Clone, PartialEq, Eq)] 
 162 pub struct PacketFrame 
{ 
 163     /// Application packet payload (chunk) 
 164     pub payload
: [u8; 25], 
 166     /// Frame counter, which provides different information depending on whether this is the last frame or not. 
 167     pub counter
: PacketFrameCounter
, 
 170 #[derive(Debug, Clone, PartialEq, Eq)] 
 171 pub enum PacketFrameCounter 
{ 
 172     /// Any packet frame that comes after the LSF and is not the final frame. 
 174         /// Which frame this is in the superframe, from 0 to 31 inclusive. 
 176         /// If a 33rd frame exists (index 32), it will be a `FinalFrame` instead. 
 178         /// All 25 bytes of of `payload` are filled and valid. 
 181     /// The final frame in the packet superframe. 
 183         /// The number of bytes in `payload` that are filled. 
 188 pub struct LichCollection([Option
<[u8; 5]>; 6]); 
 190 impl LichCollection 
{ 
 191     pub fn new() -> Self { 
 195     pub fn valid_segments(&self) -> usize { 
 196         self.0.iter
().filter
(|s
| s
.is
_some
()).count() 
 199     pub fn set_segment(&mut self, counter
: u8, part
: [u8; 5]) { 
 200         self.0[counter 
as usize] = Some(part
); 
 203     pub fn try_assemble(&self) -> Option
<[u8; 30]> { 
 204         let mut out 
= [0u8; 30]; 
 205         for (i
, segment
) in self.0.iter
().enumerate() { 
 206             let Some(segment
) = segment 
else { 
 209             for (j
, seg_val
) in segment
.iter
().enumerate() { 
 210                 out
[i 
* 5 + j
] = *seg_val
; 
 217 impl Default 
for LichCollection 
{ 
 218     fn default() -> Self {