xref: /xiu/protocol/rtsp/src/rtsp_transport.rs (revision b36cf5da)
1 use crate::global_trait::Marshal;
2 
3 use super::global_trait::Unmarshal;
4 use super::rtsp_utils::scanf;
5 
6 #[derive(Debug, Clone, Default, PartialEq)]
7 
8 pub enum CastType {
9     Multicast,
10     #[default]
11     Unicast,
12 }
13 #[derive(Debug, Clone, Default, PartialEq)]
14 pub enum ProtocolType {
15     #[default]
16     TCP,
17     UDP,
18 }
19 #[derive(Debug, Clone, Default)]
20 pub struct RtspTransport {
21     pub cast_type: CastType,
22     pub protocol_type: ProtocolType,
23     pub interleaved: Option<[u8; 2]>,
24     pub transport_mod: Option<String>,
25     pub client_port: Option<[u16; 2]>,
26     pub server_port: Option<[u16; 2]>,
27     pub ssrc: Option<u32>,
28 }
29 
30 impl Unmarshal for RtspTransport {
unmarshal(raw_data: &str) -> Option<Self>31     fn unmarshal(raw_data: &str) -> Option<Self> {
32         let mut rtsp_transport = RtspTransport::default();
33 
34         let param_parts: Vec<&str> = raw_data.split(';').collect();
35         for part in param_parts {
36             let kv: Vec<&str> = part.split('=').collect();
37             match kv[0] {
38                 "RTP/AVP/TCP" => {
39                     rtsp_transport.protocol_type = ProtocolType::TCP;
40                 }
41                 "RTP/AVP/UDP" | "RTP/AVP" => {
42                     rtsp_transport.protocol_type = ProtocolType::UDP;
43                 }
44                 "unicast" => {
45                     rtsp_transport.cast_type = CastType::Unicast;
46                 }
47                 "multicast" => {
48                     rtsp_transport.cast_type = CastType::Multicast;
49                 }
50                 "mode" => {
51                     rtsp_transport.transport_mod = Some(kv[1].to_string());
52                 }
53                 "client_port" => {
54                     let ports = scanf!(kv[1], '-', u16, u16);
55 
56                     let mut client_ports: [u16; 2] = [0, 0];
57                     if let Some(port) = ports.0 {
58                         client_ports[0] = port;
59                     }
60                     if let Some(port) = ports.1 {
61                         client_ports[1] = port;
62                     }
63 
64                     rtsp_transport.client_port = Some(client_ports);
65                 }
66                 "server_port" => {
67                     let ports = scanf!(kv[1], '-', u16, u16);
68 
69                     let mut server_ports: [u16; 2] = [0, 0];
70                     if let Some(port) = ports.0 {
71                         server_ports[0] = port;
72                     }
73                     if let Some(port) = ports.1 {
74                         server_ports[1] = port;
75                     }
76 
77                     rtsp_transport.server_port = Some(server_ports);
78                 }
79                 "interleaved" => {
80                     let vals = scanf!(kv[1], '-', u8, u8);
81 
82                     let mut interleaveds: [u8; 2] = [0, 0];
83                     if let Some(val) = vals.0 {
84                         interleaveds[0] = val;
85                     }
86                     if let Some(val) = vals.1 {
87                         interleaveds[1] = val;
88                     }
89 
90                     rtsp_transport.interleaved = Some(interleaveds);
91                 }
92                 "ssrc" => {
93                     if let Ok(ssrc) = kv[1].parse::<u32>() {
94                         rtsp_transport.ssrc = Some(ssrc);
95                     }
96                 }
97 
98                 _ => {}
99             }
100         }
101 
102         Some(rtsp_transport)
103     }
104 }
105 
106 impl Marshal for RtspTransport {
marshal(&self) -> String107     fn marshal(&self) -> String {
108         let protocol_type = match self.protocol_type {
109             ProtocolType::TCP => "RTP/AVP/TCP",
110             ProtocolType::UDP => "RTP/AVP/UDP",
111         };
112 
113         let cast_type = match self.cast_type {
114             CastType::Multicast => "multicast",
115             CastType::Unicast => "unicast",
116         };
117 
118         let client_port = if let Some(client_ports) = self.client_port {
119             format!("client_port={}-{};", client_ports[0], client_ports[1])
120         } else {
121             String::from("")
122         };
123 
124         let server_port = if let Some(server_ports) = self.server_port {
125             format!("server_port={}-{};", server_ports[0], server_ports[1])
126         } else {
127             String::from("")
128         };
129 
130         let interleaved = if let Some(interleaveds) = self.interleaved {
131             format!("interleaved={}-{};", interleaveds[0], interleaveds[1])
132         } else {
133             String::from("")
134         };
135 
136         let ssrc = if let Some(ssrc) = self.ssrc {
137             format!("ssrc={ssrc};")
138         } else {
139             String::from("")
140         };
141 
142         let mode = if let Some(mode) = &self.transport_mod {
143             format!("mode={mode}")
144         } else {
145             String::from("")
146         };
147 
148         format!("{protocol_type};{cast_type};{client_port}{server_port}{interleaved}{ssrc}{mode}")
149     }
150 }
151 
152 #[cfg(test)]
153 mod tests {
154 
155     use crate::global_trait::Marshal;
156     use crate::global_trait::Unmarshal;
157 
158     use super::RtspTransport;
159 
160     #[test]
test_parse_transport()161     fn test_parse_transport() {
162         let parser = RtspTransport::unmarshal(
163             "RTP/AVP;unicast;client_port=8000-8001;server_port=9000-9001;ssrc=1234;interleaved=0-1;mode=record",
164         ).unwrap();
165 
166         println!(" parser: {parser:?}");
167 
168         // assert_eq!(parser.cast_type, CastType::Unicast);
169         // assert_eq!(parser.protocol_type, ProtocolType::UDP);
170         // assert_eq!(parser.interleaved.unwrap(), [0, 1]);
171         // assert_eq!(parser.transport_mod.unwrap(), "record".to_string());
172         // assert_eq!(parser.client_port.unwrap(), [8000, 8001]);
173         // assert_eq!(parser.server_port.unwrap(), [9000, 9001]);
174         // assert_eq!(parser.ssrc.unwrap(), 1234);
175 
176         println!("marshal reslut: {}", parser.marshal());
177     }
178 }
179