xref: /xiu/protocol/rtmp/src/messages/parser.rs (revision fcc2ec9e)
1 use {
2     super::{
3         define::{msg_type_id, RtmpMessageData},
4         errors::{MessageError, MessageErrorValue},
5     },
6     crate::{
7         amf0::{amf0_markers, amf0_reader::Amf0Reader},
8         chunk::ChunkInfo,
9         config,
10         protocol_control_messages::reader::ProtocolControlMessageReader,
11         user_control_messages::reader::EventMessagesReader,
12         utils,
13     },
14     networkio::bytes_reader::BytesReader,
15 };
16 
17 pub struct MessageParser {
18     chunk_info: ChunkInfo,
19     session_type: u8,
20 }
21 
22 impl MessageParser {
23     pub fn new(chunk_info: ChunkInfo, session_type: u8) -> Self {
24         Self {
25             chunk_info: chunk_info,
26             session_type: session_type,
27         }
28     }
29     pub fn parse(&mut self) -> Result<RtmpMessageData, MessageError> {
30         let mut reader = BytesReader::new(self.chunk_info.payload.clone());
31 
32         match self.chunk_info.message_header.msg_type_id {
33             msg_type_id::COMMAND_AMF0 | msg_type_id::COMMAND_AMF3 => {
34                 // print!(
35                 //     "amf command:msg_length{}\n",
36                 //     self.chunk_info.message_header.msg_length
37                 // );
38 
39                 if self.chunk_info.message_header.msg_type_id == msg_type_id::COMMAND_AMF3 {
40                     reader.read_u8()?;
41                 }
42                 let mut amf_reader = Amf0Reader::new(reader);
43 
44                 //utils::print::print(amf_reader.get_remaining_bytes());
45 
46                 let command_name = amf_reader.read_with_type(amf0_markers::STRING)?;
47                 // match command_name.clone(){
48                 //     Amf0ValueType::UTF8String(val) =>{
49                 //         print!("command name : {}\n",val);
50 
51                 //         if val == "deleteStream"{
52                 //             let aa = 4;
53                 //         }
54                 //     }
55                 //     _ =>{}
56                 // }
57                 let transaction_id = amf_reader.read_with_type(amf0_markers::NUMBER)?;
58 
59                 // print!("2222222222222 command name  transction id \n");
60                 // utils::print::print(amf_reader.get_remaining_bytes());
61 
62                 //The third value can be an object or NULL object
63                 let command_obj_raw = amf_reader.read_with_type(amf0_markers::OBJECT);
64                 let command_obj = match command_obj_raw {
65                     Ok(val) => val,
66                     Err(_) => amf_reader.read_with_type(amf0_markers::NULL)?,
67                 };
68 
69                 let others = amf_reader.read_all()?;
70 
71                 return Ok(RtmpMessageData::Amf0Command {
72                     command_name: command_name,
73                     transaction_id: transaction_id,
74                     command_object: command_obj,
75                     others,
76                 });
77             }
78 
79             msg_type_id::AUDIO => {
80                 if config::DEBUG && ((config::DEBUG_INFO_TYPE & self.session_type) > 0) {
81                     print!(
82                         "audio:msg_length{}\n",
83                         self.chunk_info.message_header.msg_length
84                     );
85                 }
86 
87                 return Ok(RtmpMessageData::AudioData {
88                     data: self.chunk_info.payload.clone(),
89                 });
90             }
91             msg_type_id::VIDEO => {
92                 if config::DEBUG && ((config::DEBUG_INFO_TYPE & self.session_type) > 0) {
93                     print!(
94                         "video:msg_length{}\n",
95                         self.chunk_info.message_header.msg_length
96                     );
97                 }
98                 return Ok(RtmpMessageData::VideoData {
99                     data: self.chunk_info.payload.clone(),
100                 });
101             }
102             msg_type_id::USER_CONTROL_EVENT => {
103                 print!(
104                     "user control event:msg_length{}\n",
105                     self.chunk_info.message_header.msg_length
106                 );
107                 let data = EventMessagesReader::new(reader).parse_event()?;
108                 return Ok(data);
109             }
110             msg_type_id::SET_CHUNK_SIZE => {
111                 let chunk_size = ProtocolControlMessageReader::new(reader).read_set_chunk_size()?;
112                 return Ok(RtmpMessageData::SetChunkSize {
113                     chunk_size: chunk_size,
114                 });
115             }
116             msg_type_id::ABORT => {
117                 let chunk_stream_id =
118                     ProtocolControlMessageReader::new(reader).read_abort_message()?;
119                 return Ok(RtmpMessageData::AbortMessage {
120                     chunk_stream_id: chunk_stream_id,
121                 });
122             }
123             msg_type_id::ACKNOWLEDGEMENT => {
124                 let sequence_number =
125                     ProtocolControlMessageReader::new(reader).read_acknowledgement()?;
126                 return Ok(RtmpMessageData::Acknowledgement {
127                     sequence_number: sequence_number,
128                 });
129             }
130             msg_type_id::WIN_ACKNOWLEDGEMENT_SIZE => {
131                 let size =
132                     ProtocolControlMessageReader::new(reader).read_window_acknowledgement_size()?;
133                 return Ok(RtmpMessageData::WindowAcknowledgementSize { size: size });
134             }
135             msg_type_id::SET_PEER_BANDWIDTH => {
136                 let properties =
137                     ProtocolControlMessageReader::new(reader).read_set_peer_bandwidth()?;
138                 return Ok(RtmpMessageData::SetPeerBandwidth {
139                     properties: properties,
140                 });
141             }
142             msg_type_id::DATA_AMF0 | msg_type_id::DATA_AMF3 => {
143                 //let values = Amf0Reader::new(reader).read_all()?;
144                 return Ok(RtmpMessageData::AmfData {
145                     raw_data: self.chunk_info.payload.clone(),
146                 });
147             }
148 
149             msg_type_id::SHARED_OBJ_AMF3 | msg_type_id::SHARED_OBJ_AMF0 => {}
150 
151             msg_type_id::AGGREGATE => {}
152 
153             _ => {
154                 return Err(MessageError {
155                     value: MessageErrorValue::UnknowMessageType,
156                 });
157             }
158         }
159         return Err(MessageError {
160             value: MessageErrorValue::UnknowMessageType,
161         });
162     }
163 }
164 
165 #[cfg(test)]
166 mod tests {
167 
168     use super::MessageParser;
169     use crate::chunk::unpacketizer::ChunkUnpacketizer;
170     use crate::chunk::unpacketizer::UnpackResult;
171 
172     #[test]
173     fn test_message_parse() {
174         let mut unpacker = ChunkUnpacketizer::new();
175 
176         let data: [u8; 205] = [
177             2, 0, 0, 0, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0, 16, 0, //set chunk size
178             //connect
179             3, //|format+csid|
180             0, 0, 0, //timestamp
181             0, 0, 177, //msg_length
182             20,  //msg_type_id 0x14
183             0, 0, 0, 0, //msg_stream_id
184             2, 0, 7, 99, 111, 110, 110, 101, 99, 116, 0, 63, 240, 0, 0, 0, 0, 0, 0, //body
185             3, 0, 3, 97, 112, 112, 2, 0, 6, 104, 97, 114, 108, 97, 110, 0, 4, 116, 121, 112, 101,
186             2, 0, 10, 110, 111, 110, 112, 114, 105, 118, 97, 116, 101, 0, 8, 102, 108, 97, 115,
187             104, 86, 101, 114, 2, 0, 31, 70, 77, 76, 69, 47, 51, 46, 48, 32, 40, 99, 111, 109, 112,
188             97, 116, 105, 98, 108, 101, 59, 32, 70, 77, 83, 99, 47, 49, 46, 48, 41, 0, 6, 115, 119,
189             102, 85, 114, 108, 2, 0, 28, 114, 116, 109, 112, 58, 47, 47, 108, 111, 99, 97, 108,
190             104, 111, 115, 116, 58, 49, 57, 51, 53, 47, 104, 97, 114, 108, 97, 110, 0, 5, 116, 99,
191             85, 114, 108, 2, 0, 28, 114, 116, 109, 112, 58, 47, 47, 108, 111, 99, 97, 108, 104,
192             111, 115, 116, 58, 49, 57, 51, 53, 47, 104, 97, 114, 108, 97, 110, 0, 0, 9,
193         ];
194 
195         unpacker.extend_data(&data[..]);
196 
197         loop {
198             let result = unpacker.read_chunk();
199 
200             let rv = match result {
201                 Ok(val) => val,
202                 Err(_) => {
203                     print!("end-----------");
204                     return;
205                 }
206             };
207 
208             match rv {
209                 UnpackResult::ChunkInfo(chunk_info) => {
210                     let _ = chunk_info.message_header.msg_streamd_id;
211                     let _ = chunk_info.message_header.timestamp;
212 
213                     let mut message_parser = MessageParser::new(chunk_info, 15);
214                     let _ = message_parser.parse();
215                 }
216                 _ => {}
217             }
218         }
219     }
220 }
221