]>
code.octet-stream.net Git - m17rt/blob - m17core/src/tnc.rs
f3622e5c3351fa73702c8ff67a0f24a9a7d3494f
   1 use crate::kiss
::{KissBuffer
, KissFrame
}; 
   2 use crate::modem
::ModulatorFrame
; 
   3 use crate::protocol
::{Frame
, LichCollection
, LsfFrame
, Mode
, PacketFrameCounter
}; 
   5 /// Handles the KISS protocol and frame management for `SoftModulator` and `SoftDemodulator`. 
   7 /// These components work alongside each other. User is responsible for chaining them together 
   8 /// or doing something else with the data. 
  10     /// Handle framing of KISS commands from the host, which may arrive in arbitrary binary blobs. 
  11     kiss_buffer
: KissBuffer
, 
  13     /// Kiss message that needs to be sent to the host. 
  14     outgoing_kiss
: Option
<OutgoingKiss
>, 
  16     /// Current RX or TX function of the TNC. 
  21     pub fn new() -> Self { 
  23             kiss_buffer
: KissBuffer
::new(), 
  29     /// Process an individual `Frame` that has been decoded by the modem. 
  30     pub fn handle_frame(&mut self, frame
: Frame
) { 
  33                 // A new LSF implies a clean slate. 
  34                 // If we were partway through decoding something else then we missed it. 
  37                         self.state 
= State
::RxPacket(RxPacketState 
{ 
  44                         let kiss 
= KissFrame
::new_stream_setup(&lsf
.0).unwrap
(); 
  45                         self.kiss_to_host(kiss
); 
  46                         self.state 
= State
::RxStream(RxStreamState 
{ lsf
, index
: 0 }); 
  50             Frame
::Packet(packet
) => { 
  51                 match &mut self.state 
{ 
  52                     State
::RxPacket(ref mut rx
) => { 
  53                         match packet
.counter 
{ 
  54                             PacketFrameCounter
::Frame 
{ index 
} => { 
  55                                 if index 
== rx
.count 
&& index 
< 32 { 
  56                                     let start 
= 25 * index
; 
  57                                     rx
.packet
[start
..(start 
+ 25)].copy_from_slice(&packet
.payload
); 
  60                                     // unexpected order - something has gone wrong 
  61                                     self.state 
= State
::Idle
; 
  64                             PacketFrameCounter
::FinalFrame 
{ payload_len 
} => { 
  65                                 let start 
= 25 * rx
.count
; 
  66                                 let end 
= start 
+ payload_len
; 
  67                                 rx
.packet
[start
..(start 
+ payload_len
)] 
  68                                     .copy_from_slice(&packet
.payload
); 
  69                                 // TODO: compatible packets should be sent on port 0 too 
  71                                     KissFrame
::new_full_packet(&rx
.lsf
.0, &rx
.packet
[0..end
]) 
  73                                 self.kiss_to_host(kiss
); 
  74                                 self.state 
= State
::Idle
; 
  80                         self.state 
= State
::Idle
; 
  84             Frame
::Stream(stream
) => { 
  85                 match &mut self.state 
{ 
  86                     State
::RxStream(ref mut rx
) => { 
  87                         // TODO: consider wraparound from 0x7fff 
  88                         if stream
.frame
_n
umber 
< rx
.index 
{ 
  89                             let mut lich 
= LichCollection
::new(); 
  90                             lich
.set_segment(stream
.lich_idx
, stream
.lich_part
); 
  91                             self.state 
= State
::RxAcquiringStream(RxAcquiringStreamState 
{ lich 
}); 
  93                             rx
.index 
= stream
.frame
_n
umber 
+ 1; 
  94                             let kiss 
= KissFrame
::new_stream_data(&stream
).unwrap
(); 
  95                             self.kiss_to_host(kiss
); 
  96                             // TODO: end stream if LICH updates indicate non-META part has changed 
  97                             // (this implies a new station) 
  98                             if stream
.end_of_stream 
{ 
  99                                 self.state 
= State
::Idle
; 
 103                     State
::RxAcquiringStream(ref mut rx
) => { 
 104                         rx
.lich
.set_segment(stream
.lich_idx
, stream
.lich_part
); 
 105                         if let Some(maybe_lsf
) = rx
.lich
.try_assemble() { 
 106                             let lsf 
= LsfFrame(maybe_lsf
); 
 107                             // LICH can change mid-transmission so wait until the CRC is correct 
 108                             // to ensure (to high probability) we haven't done a "torn read" 
 110                                 let kiss 
= KissFrame
::new_stream_setup(&lsf
.0).unwrap
(); 
 111                                 self.kiss_to_host(kiss
); 
 112                                 // TODO: avoid discarding the first data payload here 
 113                                 // need a queue depth of 2 for outgoing kiss 
 114                                 self.state 
= State
::RxStream(RxStreamState 
{ 
 116                                     index
: stream
.frame
_n
umber 
+ 1, 
 122                         // If coming from another state, we have missed something. 
 123                         // Never mind, let's start tracking LICH. 
 124                         let mut lich 
= LichCollection
::new(); 
 125                         lich
.set_segment(stream
.lich_idx
, stream
.lich_part
); 
 126                         self.state 
= State
::RxAcquiringStream(RxAcquiringStreamState 
{ lich 
}) 
 133     pub fn set_data_carrier_detect(&mut self, _dcd
: bool
) {} 
 135     pub fn set_now(&mut self, samples
: u64) {} 
 137     pub fn set_tx_end_time(&mut self, in_samples
: usize) { 
 138         // This is a relative time from now, expressed in samples 
 139         // Use the time from set_now() to decide when to drop PTT 
 142     pub fn read_tx_frame(&mut self) -> Option
<ModulatorFrame
> { 
 143         // yes we want to deal with frames here 
 144         // it's important to establish successful decode that SoftDemodulator is aware of the frame innards 
 148     /// Read KISS message to be sent to host. 
 150     /// After each frame input, this should be consumed in a loop until length 0 is returned. 
 151     /// This component will never block. Upstream interface can provide blocking `read()` if desired. 
 152     pub fn read_kiss(&mut self, target_buf
: &mut [u8]) -> usize { 
 153         match self.outgoing_kiss
.as_mut() { 
 155                 let n 
= (outgoing
.kiss_frame
.len 
- outgoing
.sent
).min(target_buf
.len()); 
 157                     .copy_from_slice(&outgoing
.kiss_frame
.data
[outgoing
.sent
..(outgoing
.sent 
+ n
)]); 
 159                 if outgoing
.sent 
== outgoing
.kiss_frame
.len 
{ 
 160                     self.outgoing_kiss 
= None
; 
 168     pub fn write_kiss(&mut self, buf
: &[u8]) -> usize { 
 169         let target_buf 
= self.kiss_buffer
.buf_remaining(); 
 170         let n 
= buf
.len().min(target_buf
.len()); 
 171         target_buf
[0..n
].copy_from_slice(&buf
[0..n
]); 
 172         self.kiss_buffer
.did_write(n
); 
 173         while let Some(_kiss_frame
) = self.kiss_buffer
.next_frame() { 
 174             // TODO: handle host-to-TNC message 
 179     fn kiss_to_host(&mut self, kiss_frame
: KissFrame
) { 
 180         self.outgoing_kiss 
= Some(OutgoingKiss 
{ 
 187 #[derive(Debug, PartialEq, Eq, Clone)] 
 188 pub enum SoftTncError 
{ 
 189     General(&'
static str), 
 193 struct OutgoingKiss 
{ 
 194     kiss_frame
: KissFrame
, 
 199     /// Nothing happening. 
 202     /// We received some stream data but missed the leading LSF so we are trying to assemble from LICH. 
 203     RxAcquiringStream(RxAcquiringStreamState
), 
 205     /// We have acquired an identified stream transmission and are sending data payloads to the host. 
 206     RxStream(RxStreamState
), 
 208     /// We are receiving a packet. All is well so far, and there is more data to come before we tell the host. 
 209     RxPacket(RxPacketState
), 
 213 struct RxAcquiringStreamState 
{ 
 214     /// Partial assembly of LSF by accumulating LICH fields. 
 215     lich
: LichCollection
, 
 218 struct RxStreamState 
{ 
 219     /// Track identifying information for this transmission so we can tell if it changes. 
 222     /// Expected next frame number. Allowed to skip values on RX, but not go backwards. 
 226 struct RxPacketState 
{ 
 230     /// Accumulation of packet data that we have received so far. 
 233     /// Number of payload frames we have received. If we are stably in the RxPacket state, 
 234     /// this will be between 0 and 32 inclusive. 
 241     use crate::kiss
::{KissCommand
, PORT_STREAM
}; 
 242     use crate::protocol
::StreamFrame
; 
 244     // TODO: finish all handle_frame tests as below 
 245     // this will be much more straightforward when we have a way to create LSFs programatically 
 247     // receiving a single-frame packet 
 249     // receiving a multi-frame packet 
 251     // part of one packet and then another 
 254     fn tnc_receive_stream() { 
 256             255, 255, 255, 255, 255, 255, 0, 0, 0, 159, 221, 81, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
 257             0, 0, 0, 0, 0, 131, 53, 
 259         let stream1 
= StreamFrame 
{ 
 261             lich_part
: [255, 255, 255, 255, 255], 
 263             end_of_stream
: false, 
 265                 128, 0, 119, 115, 220, 252, 41, 235, 8, 0, 116, 195, 94, 244, 45, 75, 
 268         let stream2 
= StreamFrame 
{ 
 270             lich_part
: [255, 0, 0, 0, 159], 
 274                 17, 0, 94, 82, 216, 135, 181, 15, 30, 0, 125, 195, 152, 183, 41, 57, 
 277         let mut tnc 
= SoftTnc
::new(); 
 278         let mut kiss 
= KissFrame
::new_empty(); 
 279         assert_eq
!(tnc
.read_kiss(&mut kiss
.data
), 0); 
 281         tnc
.handle_frame(Frame
::Lsf(lsf
)); 
 282         kiss
.len 
= tnc
.read_kiss(&mut kiss
.data
); 
 283         assert_eq
!(kiss
.command().unwrap
(), KissCommand
::DataFrame
); 
 284         assert_eq
!(kiss
.port().unwrap
(), PORT_STREAM
); 
 286         let mut payload_buf 
= [0u8; 2048]; 
 287         let n 
= kiss
.decode_payload(&mut payload_buf
).unwrap
(); 
 290         tnc
.handle_frame(Frame
::Stream(stream1
)); 
 291         kiss
.len 
= tnc
.read_kiss(&mut kiss
.data
); 
 292         assert_eq
!(kiss
.command().unwrap
(), KissCommand
::DataFrame
); 
 293         assert_eq
!(kiss
.port().unwrap
(), PORT_STREAM
); 
 295         let n 
= kiss
.decode_payload(&mut payload_buf
).unwrap
(); 
 298         tnc
.handle_frame(Frame
::Stream(stream2
)); 
 299         kiss
.len 
= tnc
.read_kiss(&mut kiss
.data
); 
 300         assert_eq
!(kiss
.command().unwrap
(), KissCommand
::DataFrame
); 
 301         assert_eq
!(kiss
.port().unwrap
(), PORT_STREAM
); 
 303         let n 
= kiss
.decode_payload(&mut payload_buf
).unwrap
(); 
 308     fn tnc_acquire_stream() { 
 312                 lich_part
: [255, 255, 255, 255, 255], 
 314                 end_of_stream
: false, 
 316                     128, 0, 119, 115, 220, 252, 41, 235, 8, 0, 116, 195, 94, 244, 45, 75, 
 321                 lich_part
: [255, 0, 0, 0, 159], 
 323                 end_of_stream
: false, 
 325                     17, 0, 94, 82, 216, 135, 181, 15, 30, 0, 125, 195, 152, 183, 41, 57, 
 330                 lich_part
: [221, 81, 5, 5, 0], 
 332                 end_of_stream
: false, 
 334                     17, 128, 93, 74, 154, 167, 169, 11, 20, 0, 116, 91, 158, 220, 45, 111, 
 339                 lich_part
: [0, 0, 0, 0, 0], 
 341                 end_of_stream
: false, 
 343                     15, 128, 114, 83, 218, 252, 59, 111, 31, 128, 116, 91, 84, 231, 45, 105, 
 348                 lich_part
: [0, 0, 0, 0, 0], 
 350                 end_of_stream
: false, 
 352                     9, 128, 119, 115, 220, 220, 57, 15, 48, 128, 124, 83, 158, 236, 181, 91, 
 357                 lich_part
: [0, 0, 0, 131, 53], 
 359                 end_of_stream
: false, 
 361                     52, 0, 116, 90, 152, 167, 225, 216, 32, 0, 116, 83, 156, 212, 33, 216, 
 366         let mut tnc 
= SoftTnc
::new(); 
 367         let mut kiss 
= KissFrame
::new_empty(); 
 369             tnc
.handle_frame(Frame
::Stream(f
)); 
 371         kiss
.len 
= tnc
.read_kiss(&mut kiss
.data
); 
 372         let mut payload_buf 
= [0u8; 2048]; 
 373         let n 
= kiss
.decode_payload(&mut payload_buf
).unwrap
(); 
 378                 255, 255, 255, 255, 255, 255, 0, 0, 0, 159, 221, 81, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 
 379                 0, 0, 0, 0, 0, 0, 131, 53, 
 385     fn tnc_handle_skipped_stream_frame() { 
 387             255, 255, 255, 255, 255, 255, 0, 0, 0, 159, 221, 81, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
 388             0, 0, 0, 0, 0, 131, 53, 
 390         let stream1 
= StreamFrame 
{ 
 392             lich_part
: [255, 255, 255, 255, 255], 
 394             end_of_stream
: false, 
 396                 128, 0, 119, 115, 220, 252, 41, 235, 8, 0, 116, 195, 94, 244, 45, 75, 
 399         let stream3 
= StreamFrame 
{ 
 401             lich_part
: [221, 81, 5, 5, 0], 
 403             end_of_stream
: false, 
 405                 17, 128, 93, 74, 154, 167, 169, 11, 20, 0, 116, 91, 158, 220, 45, 111, 
 408         let mut tnc 
= SoftTnc
::new(); 
 409         let mut kiss 
= KissFrame
::new_empty(); 
 410         assert_eq
!(tnc
.read_kiss(&mut kiss
.data
), 0); 
 412         tnc
.handle_frame(Frame
::Lsf(lsf
)); 
 413         kiss
.len 
= tnc
.read_kiss(&mut kiss
.data
); 
 414         assert_eq
!(kiss
.command().unwrap
(), KissCommand
::DataFrame
); 
 415         assert_eq
!(kiss
.port().unwrap
(), PORT_STREAM
); 
 417         let mut payload_buf 
= [0u8; 2048]; 
 418         let n 
= kiss
.decode_payload(&mut payload_buf
).unwrap
(); 
 421         tnc
.handle_frame(Frame
::Stream(stream1
)); 
 422         kiss
.len 
= tnc
.read_kiss(&mut kiss
.data
); 
 423         assert_eq
!(kiss
.command().unwrap
(), KissCommand
::DataFrame
); 
 424         assert_eq
!(kiss
.port().unwrap
(), PORT_STREAM
); 
 426         let n 
= kiss
.decode_payload(&mut payload_buf
).unwrap
(); 
 429         tnc
.handle_frame(Frame
::Stream(stream3
)); 
 430         kiss
.len 
= tnc
.read_kiss(&mut kiss
.data
); 
 431         assert_eq
!(kiss
.command().unwrap
(), KissCommand
::DataFrame
); 
 432         assert_eq
!(kiss
.port().unwrap
(), PORT_STREAM
); 
 434         let n 
= kiss
.decode_payload(&mut payload_buf
).unwrap
();