]>
code.octet-stream.net Git - m17rt/blob - m17core/src/reflector/convert.rs
1 //! Utilities for converting streams between UDP and RF representations
3 use crate::protocol
::{LsfFrame
, StreamFrame
};
5 use super::packet
::Voice
;
7 /// Accepts `Voice` packets from a reflector and turns them into LSF and Stream frames.
9 /// This is the format required for the voice data to cross the KISS protocol boundary.
10 pub struct VoiceToRf
{
11 /// Link Setup most recently acquired
12 lsf
: Option
<LsfFrame
>,
13 /// Which LICH part we are going to emit next, 0-5
18 pub fn new() -> Self {
25 /// For a Voice packet received from a reflector, return the frames that would be transmitted
26 /// on RF, including by reconstructing the LICH parts of the stream frame.
28 /// If this is the start of a new or different stream transmission, this returns the Link Setup
29 /// Frame which comes first, then the first associated Stream frame.
31 /// If this is a continuation of a transmission matching the previous LSF, then it returns only
33 pub fn next(&mut self, voice
: &Voice
) -> (Option
<LsfFrame
>, StreamFrame
) {
34 let this_lsf
= voice
.link_setup_frame();
35 let emit_lsf
= if Some(&this_lsf
) != self.lsf
.as_ref() {
36 self.lsf
= Some(this_lsf
.clone());
42 let lsf
= self.lsf
.as_ref().unwrap
();
43 let stream
= StreamFrame
{
44 lich_idx
: self.lich_cnt
as u8,
45 lich_part
: (&lsf
.0[self.lich_cnt
* 5..(self.lich_cnt
+ 1) * 5])
48 frame_number
: voice
.frame
_n
umber
(),
49 end_of_stream
: voice
.is
_end
_o
f_stream
(),
50 stream_data
: voice
.payload().try_into().unwrap
(),
52 let lsf
= if emit_lsf
{ self.lsf
.clone() } else { None
};
53 if voice
.is
_end
_o
f_stream
() {
60 /// Accepts LSF and stream RF payloads and merges them into `Voice` packets for reflector use.
62 /// For a series of transmissions this object should be re-used so that Stream ID is correctly
63 /// changed after each new LSF.
64 pub struct RfToVoice
{
70 pub fn new(lsf
: LsfFrame
) -> Self {
71 Self { lsf
, stream_id
: 0 }
74 pub fn process_lsf(&mut self, lsf
: LsfFrame
) {
76 self.stream_id
= self.stream_id
.wrapping_add(1);
79 pub fn process_stream(&self, stream
: &StreamFrame
) -> Voice
{
80 let mut v
= Voice
::new();
81 v
.set_stream_id(self.stream_id
);
82 v
.set_frame_number(stream
.frame
_n
umber
);
83 v
.set_end_of_stream(stream
.end_of_stream
);
84 v
.set_payload(&stream
.stream_data
);
85 v
.set_link_setup_frame(&self.lsf
);
93 address
::{Address
, Callsign
},
94 protocol
::{LsfFrame
, StreamFrame
},
97 use super::{RfToVoice
, VoiceToRf
};
100 fn convert_roundtrip() {
101 let lsf
= LsfFrame
::new_voice(
102 &Address
::Callsign(Callsign(*b
"VK7XT ")),
105 let stream
= StreamFrame
{
107 lich_part
: lsf
.0[0..5].try_into().unwrap
(),
109 end_of_stream
: false,
110 stream_data
: [1u8; 16],
112 let rf_to_voice
= RfToVoice
::new(lsf
.clone());
113 let voice
= rf_to_voice
.process_stream(&stream
);
115 let mut voice_to_rf
= VoiceToRf
::new();
116 let (lsf2
, stream2
) = voice_to_rf
.next(&voice
);
117 assert_eq
!(lsf2
, Some(lsf
));
118 assert_eq
!(stream2
, stream
);