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