]>
code.octet-stream.net Git - m17rt/blob - m17core/src/tnc.rs
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
();