]>
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
);
68 // TODO: compatible packets should be sent on port 0 too
70 KissFrame
::new_full_packet(&rx
.lsf
.0, &rx
.packet
[0..end
])
72 self.kiss_to_host(kiss
);
73 self.state
= State
::Idle
;
79 self.state
= State
::Idle
;
83 Frame
::Stream(stream
) => {
84 match &mut self.state
{
85 State
::RxStream(ref mut rx
) => {
86 // TODO: consider wraparound from 0x7fff
87 if stream
.frame
_n
umber
< rx
.index
{
88 let mut lich
= LichCollection
::new();
89 lich
.set_segment(stream
.lich_idx
, stream
.lich_part
);
90 self.state
= State
::RxAcquiringStream(RxAcquiringStreamState
{ lich
});
92 rx
.index
= stream
.frame
_n
umber
+ 1;
93 let kiss
= KissFrame
::new_stream_data(&stream
).unwrap
();
94 self.kiss_to_host(kiss
);
95 // TODO: end stream if LICH updates indicate non-META part has changed
96 // (this implies a new station)
97 if stream
.end_of_stream
{
98 self.state
= State
::Idle
;
102 State
::RxAcquiringStream(ref mut rx
) => {
103 rx
.lich
.set_segment(stream
.lich_idx
, stream
.lich_part
);
104 if let Some(maybe_lsf
) = rx
.lich
.try_assemble() {
105 let lsf
= LsfFrame(maybe_lsf
);
106 // LICH can change mid-transmission so wait until the CRC is correct
107 // to ensure (to high probability) we haven't done a "torn read"
109 let kiss
= KissFrame
::new_stream_setup(&lsf
.0).unwrap
();
110 self.kiss_to_host(kiss
);
111 // TODO: avoid discarding the first data payload here
112 // need a queue depth of 2 for outgoing kiss
113 self.state
= State
::RxStream(RxStreamState
{
115 index
: stream
.frame
_n
umber
+ 1,
121 // If coming from another state, we have missed something.
122 // Never mind, let's start tracking LICH.
123 let mut lich
= LichCollection
::new();
124 lich
.set_segment(stream
.lich_idx
, stream
.lich_part
);
125 self.state
= State
::RxAcquiringStream(RxAcquiringStreamState
{ lich
})
132 /// Update the number of samples that have been received by the incoming stream, as a form of timekeeping
133 pub fn advance_samples(&mut self, _samples
: u64) {}
135 pub fn set_data_carrier_detect(&mut self, _dcd
: bool
) {}
137 pub fn read_tx_frame(&mut self) -> Result
<Option
<Frame
>, SoftTncError
> {
138 // yes we want to deal with Frames here
139 // it's important to establish successful decode that SoftDemodulator is aware of the frame innards
143 /// Read KISS message to be sent to host.
145 /// After each frame input, this should be consumed in a loop until length 0 is returned.
146 /// This component will never block. Upstream interface can provide blocking `read()` if desired.
147 pub fn read_kiss(&mut self, target_buf
: &mut [u8]) -> usize {
148 match self.outgoing_kiss
.as_mut() {
150 let n
= (outgoing
.kiss_frame
.len
- outgoing
.sent
).min(target_buf
.len());
152 .copy_from_slice(&outgoing
.kiss_frame
.data
[outgoing
.sent
..(outgoing
.sent
+ n
)]);
154 if outgoing
.sent
== outgoing
.kiss_frame
.len
{
155 self.outgoing_kiss
= None
;
163 pub fn write_kiss(&mut self, buf
: &[u8]) -> usize {
164 let target_buf
= self.kiss_buffer
.buf_remaining();
165 let n
= buf
.len().min(target_buf
.len());
166 target_buf
[0..n
].copy_from_slice(&buf
[0..n
]);
167 self.kiss_buffer
.did_write(n
);
168 while let Some(_kiss_frame
) = self.kiss_buffer
.next_frame() {
169 // TODO: handle host-to-TNC message
174 fn kiss_to_host(&mut self, kiss_frame
: KissFrame
) {
175 self.outgoing_kiss
= Some(OutgoingKiss
{
182 #[derive(Debug, PartialEq, Eq, Clone)]
183 pub enum SoftTncError
{
184 General(&'
static str),
188 struct OutgoingKiss
{
189 kiss_frame
: KissFrame
,
194 /// Nothing happening.
197 /// We received some stream data but missed the leading LSF so we are trying to assemble from LICH.
198 RxAcquiringStream(RxAcquiringStreamState
),
200 /// We have acquired an identified stream transmission and are sending data payloads to the host.
201 RxStream(RxStreamState
),
203 /// We are receiving a packet. All is well so far, and there is more data to come before we tell the host.
204 RxPacket(RxPacketState
),
208 struct RxAcquiringStreamState
{
209 /// Partial assembly of LSF by accumulating LICH fields.
210 lich
: LichCollection
,
213 struct RxStreamState
{
214 /// Track identifying information for this transmission so we can tell if it changes.
217 /// Expected next frame number. Allowed to skip values on RX, but not go backwards.
221 struct RxPacketState
{
225 /// Accumulation of packet data that we have received so far.
228 /// Number of payload frames we have received. If we are stably in the RxPacket state,
229 /// this will be between 0 and 32 inclusive.
236 use crate::kiss
::{KissCommand
, PORT_STREAM
};
237 use crate::protocol
::StreamFrame
;
239 // TODO: finish all handle_frame tests as below
240 // this will be much more straightforward when we have a way to create LSFs programatically
242 // receiving a single-frame packet
244 // receiving a multi-frame packet
246 // part of one packet and then another
249 fn tnc_receive_stream() {
251 255, 255, 255, 255, 255, 255, 0, 0, 0, 159, 221, 81, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0,
252 0, 0, 0, 0, 0, 131, 53,
254 let stream1
= StreamFrame
{
256 lich_part
: [255, 255, 255, 255, 255],
258 end_of_stream
: false,
260 128, 0, 119, 115, 220, 252, 41, 235, 8, 0, 116, 195, 94, 244, 45, 75,
263 let stream2
= StreamFrame
{
265 lich_part
: [255, 0, 0, 0, 159],
269 17, 0, 94, 82, 216, 135, 181, 15, 30, 0, 125, 195, 152, 183, 41, 57,
272 let mut tnc
= SoftTnc
::new();
273 let mut kiss
= KissFrame
::new_empty();
274 assert_eq
!(tnc
.read_kiss(&mut kiss
.data
), 0);
276 tnc
.handle_frame(Frame
::Lsf(lsf
));
277 kiss
.len
= tnc
.read_kiss(&mut kiss
.data
);
278 assert_eq
!(kiss
.command().unwrap
(), KissCommand
::DataFrame
);
279 assert_eq
!(kiss
.port().unwrap
(), PORT_STREAM
);
281 let mut payload_buf
= [0u8; 2048];
282 let n
= kiss
.decode_payload(&mut payload_buf
).unwrap
();
285 tnc
.handle_frame(Frame
::Stream(stream1
));
286 kiss
.len
= tnc
.read_kiss(&mut kiss
.data
);
287 assert_eq
!(kiss
.command().unwrap
(), KissCommand
::DataFrame
);
288 assert_eq
!(kiss
.port().unwrap
(), PORT_STREAM
);
290 let n
= kiss
.decode_payload(&mut payload_buf
).unwrap
();
293 tnc
.handle_frame(Frame
::Stream(stream2
));
294 kiss
.len
= tnc
.read_kiss(&mut kiss
.data
);
295 assert_eq
!(kiss
.command().unwrap
(), KissCommand
::DataFrame
);
296 assert_eq
!(kiss
.port().unwrap
(), PORT_STREAM
);
298 let n
= kiss
.decode_payload(&mut payload_buf
).unwrap
();
303 fn tnc_acquire_stream() {
307 lich_part
: [255, 255, 255, 255, 255],
309 end_of_stream
: false,
311 128, 0, 119, 115, 220, 252, 41, 235, 8, 0, 116, 195, 94, 244, 45, 75,
316 lich_part
: [255, 0, 0, 0, 159],
318 end_of_stream
: false,
320 17, 0, 94, 82, 216, 135, 181, 15, 30, 0, 125, 195, 152, 183, 41, 57,
325 lich_part
: [221, 81, 5, 5, 0],
327 end_of_stream
: false,
329 17, 128, 93, 74, 154, 167, 169, 11, 20, 0, 116, 91, 158, 220, 45, 111,
334 lich_part
: [0, 0, 0, 0, 0],
336 end_of_stream
: false,
338 15, 128, 114, 83, 218, 252, 59, 111, 31, 128, 116, 91, 84, 231, 45, 105,
343 lich_part
: [0, 0, 0, 0, 0],
345 end_of_stream
: false,
347 9, 128, 119, 115, 220, 220, 57, 15, 48, 128, 124, 83, 158, 236, 181, 91,
352 lich_part
: [0, 0, 0, 131, 53],
354 end_of_stream
: false,
356 52, 0, 116, 90, 152, 167, 225, 216, 32, 0, 116, 83, 156, 212, 33, 216,
361 let mut tnc
= SoftTnc
::new();
362 let mut kiss
= KissFrame
::new_empty();
364 tnc
.handle_frame(Frame
::Stream(f
));
366 kiss
.len
= tnc
.read_kiss(&mut kiss
.data
);
367 let mut payload_buf
= [0u8; 2048];
368 let n
= kiss
.decode_payload(&mut payload_buf
).unwrap
();
373 255, 255, 255, 255, 255, 255, 0, 0, 0, 159, 221, 81, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0,
374 0, 0, 0, 0, 0, 0, 131, 53,
380 fn tnc_handle_skipped_stream_frame() {
382 255, 255, 255, 255, 255, 255, 0, 0, 0, 159, 221, 81, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0,
383 0, 0, 0, 0, 0, 131, 53,
385 let stream1
= StreamFrame
{
387 lich_part
: [255, 255, 255, 255, 255],
389 end_of_stream
: false,
391 128, 0, 119, 115, 220, 252, 41, 235, 8, 0, 116, 195, 94, 244, 45, 75,
394 let stream3
= StreamFrame
{
396 lich_part
: [221, 81, 5, 5, 0],
398 end_of_stream
: false,
400 17, 128, 93, 74, 154, 167, 169, 11, 20, 0, 116, 91, 158, 220, 45, 111,
403 let mut tnc
= SoftTnc
::new();
404 let mut kiss
= KissFrame
::new_empty();
405 assert_eq
!(tnc
.read_kiss(&mut kiss
.data
), 0);
407 tnc
.handle_frame(Frame
::Lsf(lsf
));
408 kiss
.len
= tnc
.read_kiss(&mut kiss
.data
);
409 assert_eq
!(kiss
.command().unwrap
(), KissCommand
::DataFrame
);
410 assert_eq
!(kiss
.port().unwrap
(), PORT_STREAM
);
412 let mut payload_buf
= [0u8; 2048];
413 let n
= kiss
.decode_payload(&mut payload_buf
).unwrap
();
416 tnc
.handle_frame(Frame
::Stream(stream1
));
417 kiss
.len
= tnc
.read_kiss(&mut kiss
.data
);
418 assert_eq
!(kiss
.command().unwrap
(), KissCommand
::DataFrame
);
419 assert_eq
!(kiss
.port().unwrap
(), PORT_STREAM
);
421 let n
= kiss
.decode_payload(&mut payload_buf
).unwrap
();
424 tnc
.handle_frame(Frame
::Stream(stream3
));
425 kiss
.len
= tnc
.read_kiss(&mut kiss
.data
);
426 assert_eq
!(kiss
.command().unwrap
(), KissCommand
::DataFrame
);
427 assert_eq
!(kiss
.port().unwrap
(), PORT_STREAM
);
429 let n
= kiss
.decode_payload(&mut payload_buf
).unwrap
();