]>
code.octet-stream.net Git - m17rt/blob - m17core/src/tnc.rs
1 use crate::kiss
::{KissBuffer
, KissFrame
};
2 use crate::protocol
::{Frame
, LichCollection
, LsfFrame
, Mode
, PacketFrameCounter
};
4 /// Handles the KISS protocol and frame management for `SoftModulator` and `SoftDemodulator`.
6 /// These components work alongside each other. User is responsible for chaining them together
7 /// or doing something else with the data.
9 /// Handle framing of KISS commands from the host, which may arrive in arbitrary binary blobs.
10 kiss_buffer
: KissBuffer
,
12 /// Kiss message that needs to be sent to the host.
13 outgoing_kiss
: Option
<OutgoingKiss
>,
15 /// Current RX or TX function of the TNC.
20 pub fn new() -> Self {
22 kiss_buffer
: KissBuffer
::new(),
28 /// Process an individual `Frame` that has been decoded by the modem.
29 pub fn handle_frame(&mut self, frame
: Frame
) {
32 // A new LSF implies a clean slate.
33 // If we were partway through decoding something else then we missed it.
36 self.state
= State
::RxPacket(RxPacketState
{
43 let kiss
= KissFrame
::new_stream_setup(&lsf
.0).unwrap
();
44 self.kiss_to_host(kiss
);
45 self.state
= State
::RxStream(RxStreamState
{ lsf
, index
: 0 });
49 Frame
::Packet(packet
) => {
50 match &mut self.state
{
51 State
::RxPacket(ref mut rx
) => {
52 match packet
.counter
{
53 PacketFrameCounter
::Frame
{ index
} => {
54 if index
== rx
.count
&& index
< 32 {
55 let start
= 25 * index
;
56 rx
.packet
[start
..(start
+ 25)].copy_from_slice(&packet
.payload
);
59 // unexpected order - something has gone wrong
60 self.state
= State
::Idle
;
63 PacketFrameCounter
::FinalFrame
{ payload_len
} => {
64 let start
= 25 * rx
.count
;
65 let end
= start
+ payload_len
;
66 rx
.packet
[start
..(start
+ payload_len
)]
67 .copy_from_slice(&packet
.payload
);
69 KissFrame
::new_full_packet(&rx
.lsf
.0, &rx
.packet
[0..end
])
71 self.kiss_to_host(kiss
);
72 self.state
= State
::Idle
;
78 self.state
= State
::Idle
;
82 Frame
::Stream(stream
) => {
83 match &mut self.state
{
84 State
::RxStream(ref mut rx
) => {
85 // TODO: consider wraparound from 0x7fff
86 if stream
.frame
_n
umber
< rx
.index
{
87 let mut lich
= LichCollection
::new();
88 lich
.set_segment(stream
.lich_idx
, stream
.lich_part
);
89 self.state
= State
::RxAcquiringStream(RxAcquiringStreamState
{ lich
});
91 rx
.index
= stream
.frame
_n
umber
+ 1;
92 let kiss
= KissFrame
::new_stream_data(&stream
).unwrap
();
93 self.kiss_to_host(kiss
);
94 // TODO: end stream if LICH updates indicate non-META part has changed
95 // (this implies a new station)
96 if stream
.end_of_stream
{
97 self.state
= State
::Idle
;
101 State
::RxAcquiringStream(ref mut rx
) => {
102 rx
.lich
.set_segment(stream
.lich_idx
, stream
.lich_part
);
103 if let Some(maybe_lsf
) = rx
.lich
.try_assemble() {
104 let lsf
= LsfFrame(maybe_lsf
);
105 // LICH can change mid-transmission so wait until the CRC is correct
106 // to ensure (to high probability) we haven't done a "torn read"
108 let kiss
= KissFrame
::new_stream_setup(&lsf
.0).unwrap
();
109 self.kiss_to_host(kiss
);
110 // TODO: avoid discarding the first data payload here
111 // need a queue depth of 2 for outgoing kiss
112 self.state
= State
::RxStream(RxStreamState
{
114 index
: stream
.frame
_n
umber
+ 1,
120 // If coming from another state, we have missed something.
121 // Never mind, let's start tracking LICH.
122 let mut lich
= LichCollection
::new();
123 lich
.set_segment(stream
.lich_idx
, stream
.lich_part
);
124 self.state
= State
::RxAcquiringStream(RxAcquiringStreamState
{ lich
})
131 /// Update the number of samples that have been received by the incoming stream, as a form of timekeeping
132 pub fn advance_samples(&mut self, _samples
: u64) {}
134 pub fn set_data_carrier_detect(&mut self, _dcd
: bool
) {}
136 pub fn read_tx_frame(&mut self) -> Result
<Option
<Frame
>, SoftTncError
> {
137 // yes we want to deal with Frames here
138 // it's important to establish successful decode that SoftDemodulator is aware of the frame innards
142 /// Read KISS message to be sent to host.
144 /// After each frame input, this should be consumed in a loop until length 0 is returned.
145 /// This component will never block. Upstream interface can provide blocking `read()` if desired.
146 pub fn read_kiss(&mut self, target_buf
: &mut [u8]) -> usize {
147 match self.outgoing_kiss
.as_mut() {
149 let n
= (outgoing
.kiss_frame
.len
- outgoing
.sent
).min(target_buf
.len());
151 .copy_from_slice(&outgoing
.kiss_frame
.data
[outgoing
.sent
..(outgoing
.sent
+ n
)]);
153 if outgoing
.sent
== outgoing
.kiss_frame
.len
{
154 self.outgoing_kiss
= None
;
162 pub fn write_kiss(&mut self, buf
: &[u8]) -> usize {
163 let target_buf
= self.kiss_buffer
.buf_remaining();
164 let n
= buf
.len().min(target_buf
.len());
165 target_buf
[0..n
].copy_from_slice(&buf
[0..n
]);
166 self.kiss_buffer
.did_write(n
);
167 while let Some(_kiss_frame
) = self.kiss_buffer
.next_frame() {
168 // TODO: handle host-to-TNC message
173 fn kiss_to_host(&mut self, kiss_frame
: KissFrame
) {
174 self.outgoing_kiss
= Some(OutgoingKiss
{
181 #[derive(Debug, PartialEq, Eq, Clone)]
182 pub enum SoftTncError
{
183 General(&'
static str),
187 struct OutgoingKiss
{
188 kiss_frame
: KissFrame
,
193 /// Nothing happening.
196 /// We received some stream data but missed the leading LSF so we are trying to assemble from LICH.
197 RxAcquiringStream(RxAcquiringStreamState
),
199 /// We have acquired an identified stream transmission and are sending data payloads to the host.
200 RxStream(RxStreamState
),
202 /// We are receiving a packet. All is well so far, and there is more data to come before we tell the host.
203 RxPacket(RxPacketState
),
207 struct RxAcquiringStreamState
{
208 /// Partial assembly of LSF by accumulating LICH fields.
209 lich
: LichCollection
,
212 struct RxStreamState
{
213 /// Track identifying information for this transmission so we can tell if it changes.
216 /// Expected next frame number. Allowed to skip values on RX, but not go backwards.
220 struct RxPacketState
{
224 /// Accumulation of packet data that we have received so far.
227 /// Number of payload frames we have received. If we are stably in the RxPacket state,
228 /// this will be between 0 and 32 inclusive.
235 use crate::kiss
::{KissCommand
, PORT_STREAM
};
236 use crate::protocol
::StreamFrame
;
238 // TODO: finish all handle_frame tests as below
239 // this will be much more straightforward when we have a way to create LSFs programatically
241 // receiving a single-frame packet
243 // receiving a multi-frame packet
245 // part of one packet and then another
248 fn tnc_receive_stream() {
250 255, 255, 255, 255, 255, 255, 0, 0, 0, 159, 221, 81, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0,
251 0, 0, 0, 0, 0, 131, 53,
253 let stream1
= StreamFrame
{
255 lich_part
: [255, 255, 255, 255, 255],
257 end_of_stream
: false,
259 128, 0, 119, 115, 220, 252, 41, 235, 8, 0, 116, 195, 94, 244, 45, 75,
262 let stream2
= StreamFrame
{
264 lich_part
: [255, 0, 0, 0, 159],
268 17, 0, 94, 82, 216, 135, 181, 15, 30, 0, 125, 195, 152, 183, 41, 57,
271 let mut tnc
= SoftTnc
::new();
272 let mut kiss
= KissFrame
::new_empty();
273 assert_eq
!(tnc
.read_kiss(&mut kiss
.data
), 0);
275 tnc
.handle_frame(Frame
::Lsf(lsf
));
276 kiss
.len
= tnc
.read_kiss(&mut kiss
.data
);
277 assert_eq
!(kiss
.command().unwrap
(), KissCommand
::DataFrame
);
278 assert_eq
!(kiss
.port().unwrap
(), PORT_STREAM
);
280 let mut payload_buf
= [0u8; 2048];
281 let n
= kiss
.decode_payload(&mut payload_buf
).unwrap
();
284 tnc
.handle_frame(Frame
::Stream(stream1
));
285 kiss
.len
= tnc
.read_kiss(&mut kiss
.data
);
286 assert_eq
!(kiss
.command().unwrap
(), KissCommand
::DataFrame
);
287 assert_eq
!(kiss
.port().unwrap
(), PORT_STREAM
);
289 let n
= kiss
.decode_payload(&mut payload_buf
).unwrap
();
292 tnc
.handle_frame(Frame
::Stream(stream2
));
293 kiss
.len
= tnc
.read_kiss(&mut kiss
.data
);
294 assert_eq
!(kiss
.command().unwrap
(), KissCommand
::DataFrame
);
295 assert_eq
!(kiss
.port().unwrap
(), PORT_STREAM
);
297 let n
= kiss
.decode_payload(&mut payload_buf
).unwrap
();
302 fn tnc_acquire_stream() {
306 lich_part
: [255, 255, 255, 255, 255],
308 end_of_stream
: false,
310 128, 0, 119, 115, 220, 252, 41, 235, 8, 0, 116, 195, 94, 244, 45, 75,
315 lich_part
: [255, 0, 0, 0, 159],
317 end_of_stream
: false,
319 17, 0, 94, 82, 216, 135, 181, 15, 30, 0, 125, 195, 152, 183, 41, 57,
324 lich_part
: [221, 81, 5, 5, 0],
326 end_of_stream
: false,
328 17, 128, 93, 74, 154, 167, 169, 11, 20, 0, 116, 91, 158, 220, 45, 111,
333 lich_part
: [0, 0, 0, 0, 0],
335 end_of_stream
: false,
337 15, 128, 114, 83, 218, 252, 59, 111, 31, 128, 116, 91, 84, 231, 45, 105,
342 lich_part
: [0, 0, 0, 0, 0],
344 end_of_stream
: false,
346 9, 128, 119, 115, 220, 220, 57, 15, 48, 128, 124, 83, 158, 236, 181, 91,
351 lich_part
: [0, 0, 0, 131, 53],
353 end_of_stream
: false,
355 52, 0, 116, 90, 152, 167, 225, 216, 32, 0, 116, 83, 156, 212, 33, 216,
360 let mut tnc
= SoftTnc
::new();
361 let mut kiss
= KissFrame
::new_empty();
363 tnc
.handle_frame(Frame
::Stream(f
));
365 kiss
.len
= tnc
.read_kiss(&mut kiss
.data
);
366 let mut payload_buf
= [0u8; 2048];
367 let n
= kiss
.decode_payload(&mut payload_buf
).unwrap
();
372 255, 255, 255, 255, 255, 255, 0, 0, 0, 159, 221, 81, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0,
373 0, 0, 0, 0, 0, 0, 131, 53,
379 fn tnc_handle_skipped_stream_frame() {
381 255, 255, 255, 255, 255, 255, 0, 0, 0, 159, 221, 81, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0,
382 0, 0, 0, 0, 0, 131, 53,
384 let stream1
= StreamFrame
{
386 lich_part
: [255, 255, 255, 255, 255],
388 end_of_stream
: false,
390 128, 0, 119, 115, 220, 252, 41, 235, 8, 0, 116, 195, 94, 244, 45, 75,
393 let stream3
= StreamFrame
{
395 lich_part
: [221, 81, 5, 5, 0],
397 end_of_stream
: false,
399 17, 128, 93, 74, 154, 167, 169, 11, 20, 0, 116, 91, 158, 220, 45, 111,
402 let mut tnc
= SoftTnc
::new();
403 let mut kiss
= KissFrame
::new_empty();
404 assert_eq
!(tnc
.read_kiss(&mut kiss
.data
), 0);
406 tnc
.handle_frame(Frame
::Lsf(lsf
));
407 kiss
.len
= tnc
.read_kiss(&mut kiss
.data
);
408 assert_eq
!(kiss
.command().unwrap
(), KissCommand
::DataFrame
);
409 assert_eq
!(kiss
.port().unwrap
(), PORT_STREAM
);
411 let mut payload_buf
= [0u8; 2048];
412 let n
= kiss
.decode_payload(&mut payload_buf
).unwrap
();
415 tnc
.handle_frame(Frame
::Stream(stream1
));
416 kiss
.len
= tnc
.read_kiss(&mut kiss
.data
);
417 assert_eq
!(kiss
.command().unwrap
(), KissCommand
::DataFrame
);
418 assert_eq
!(kiss
.port().unwrap
(), PORT_STREAM
);
420 let n
= kiss
.decode_payload(&mut payload_buf
).unwrap
();
423 tnc
.handle_frame(Frame
::Stream(stream3
));
424 kiss
.len
= tnc
.read_kiss(&mut kiss
.data
);
425 assert_eq
!(kiss
.command().unwrap
(), KissCommand
::DataFrame
);
426 assert_eq
!(kiss
.port().unwrap
(), PORT_STREAM
);
428 let n
= kiss
.decode_payload(&mut payload_buf
).unwrap
();