dstar_gateway_core/codec/dcs/
packet.rs1use crate::header::DStarHeader;
9use crate::types::{Callsign, Module, StreamId};
10use crate::voice::VoiceFrame;
11
12#[non_exhaustive]
14#[derive(Debug, Clone, PartialEq, Eq)]
15pub enum ClientPacket {
16 Link {
18 callsign: Callsign,
20 client_module: Module,
22 reflector_module: Module,
24 reflector_callsign: Callsign,
26 gateway_type: GatewayType,
28 },
29
30 Unlink {
32 callsign: Callsign,
34 client_module: Module,
36 reflector_callsign: Callsign,
38 },
39
40 Poll {
42 callsign: Callsign,
44 reflector_callsign: Callsign,
46 },
47
48 Voice {
50 header: DStarHeader,
52 stream_id: StreamId,
54 seq: u8,
56 frame: VoiceFrame,
58 is_end: bool,
60 },
61}
62
63#[non_exhaustive]
65#[derive(Debug, Clone, PartialEq, Eq)]
66pub enum ServerPacket {
67 ConnectAck {
69 callsign: Callsign,
71 reflector_module: Module,
73 },
74
75 ConnectNak {
77 callsign: Callsign,
79 reflector_module: Module,
81 },
82
83 PollEcho {
85 callsign: Callsign,
87 reflector_callsign: Callsign,
89 },
90
91 Voice {
93 header: DStarHeader,
95 stream_id: StreamId,
97 seq: u8,
99 frame: VoiceFrame,
101 is_end: bool,
103 },
104}
105
106#[non_exhaustive]
108#[derive(Debug, Clone, Copy, PartialEq, Eq)]
109pub enum ConnectResult {
110 Accept,
112 Reject,
114}
115
116#[non_exhaustive]
122#[derive(Debug, Clone, Copy, PartialEq, Eq)]
123pub enum GatewayType {
124 Repeater,
126 Hotspot,
128 Dongle,
130 StarNet,
132}
133
134#[cfg(test)]
135mod tests {
136 use super::*;
137
138 #[test]
139 fn gateway_type_variants_distinct() {
140 assert_ne!(GatewayType::Repeater, GatewayType::Hotspot);
141 assert_ne!(GatewayType::Dongle, GatewayType::StarNet);
142 assert_ne!(GatewayType::Repeater, GatewayType::Dongle);
143 }
144
145 const CS_W1AW: Callsign = Callsign::from_wire_bytes(*b"W1AW ");
146 const CS_DCS001: Callsign = Callsign::from_wire_bytes(*b"DCS001 ");
147
148 #[test]
149 fn client_packet_link_constructible() {
150 let p = ClientPacket::Link {
151 callsign: CS_W1AW,
152 client_module: Module::B,
153 reflector_module: Module::C,
154 reflector_callsign: CS_DCS001,
155 gateway_type: GatewayType::Hotspot,
156 };
157 assert!(matches!(p, ClientPacket::Link { .. }));
158 }
159
160 #[test]
161 fn client_packet_unlink_constructible() {
162 let p = ClientPacket::Unlink {
163 callsign: CS_W1AW,
164 client_module: Module::B,
165 reflector_callsign: CS_DCS001,
166 };
167 assert!(matches!(p, ClientPacket::Unlink { .. }));
168 }
169
170 #[test]
171 fn client_packet_poll_constructible() {
172 let p = ClientPacket::Poll {
173 callsign: CS_W1AW,
174 reflector_callsign: CS_DCS001,
175 };
176 assert!(matches!(p, ClientPacket::Poll { .. }));
177 }
178
179 #[test]
180 fn server_packet_connect_ack_carries_module() {
181 let p = ServerPacket::ConnectAck {
182 callsign: CS_DCS001,
183 reflector_module: Module::C,
184 };
185 assert!(
186 matches!(p, ServerPacket::ConnectAck { reflector_module, .. } if reflector_module == Module::C),
187 "expected ConnectAck with Module::C, got {p:?}"
188 );
189 }
190
191 #[test]
192 fn server_packet_poll_echo_constructible() {
193 let p = ServerPacket::PollEcho {
194 callsign: CS_DCS001,
195 reflector_callsign: CS_DCS001,
196 };
197 assert!(matches!(p, ServerPacket::PollEcho { .. }));
198 }
199
200 #[test]
201 fn connect_result_variants_distinct() {
202 assert_ne!(ConnectResult::Accept, ConnectResult::Reject);
203 }
204}