1
1
use super :: * ;
2
2
3
+ const RLE_REPORT_BLOCK_MIN_LENGTH : u16 = 9 ;
4
+
3
5
/// ChunkType enumerates the three kinds of chunks described in RFC 3611 section 4.1.
4
6
#[ derive( Debug , Copy , Clone , PartialEq ) ]
5
7
pub enum ChunkType {
@@ -46,7 +48,6 @@ impl fmt::Display for Chunk {
46
48
}
47
49
ChunkType :: BitVector => write ! ( f, "[BitVector {:#b}" , self . value( ) ) ,
48
50
ChunkType :: TerminatingNull => write ! ( f, "[TerminatingNull]" ) ,
49
- //_ => write!(f, "[{:#x}]", self.0),
50
51
}
51
52
}
52
53
}
@@ -78,7 +79,6 @@ impl Chunk {
78
79
ChunkType :: RunLength => self . 0 & 0x3FFF ,
79
80
ChunkType :: BitVector => self . 0 & 0x7FFF ,
80
81
ChunkType :: TerminatingNull => 0 ,
81
- //_ => self.0,
82
82
}
83
83
}
84
84
}
@@ -103,107 +103,141 @@ impl Chunk {
103
103
/// | chunk n-1 | chunk n |
104
104
/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
105
105
#[ derive( Debug , Default , PartialEq , Clone ) ]
106
- pub struct RleReportBlock {
107
- pub xr_header : XRHeader ,
106
+ pub struct RLEReportBlock {
107
+ pub is_loss_rle : bool ,
108
108
pub t : u8 ,
109
109
pub ssrc : u32 ,
110
110
pub begin_seq : u16 ,
111
111
pub end_seq : u16 ,
112
112
pub chunks : Vec < Chunk > ,
113
113
}
114
114
115
- impl RleReportBlock {
116
- fn raw_size ( & self ) -> usize {
117
- 4 + 1 + 4 + 2 + 2 + self . chunks . len ( ) * 2
118
- }
119
- }
120
-
121
115
/// LossRLEReportBlock is used to report information about packet
122
116
/// losses, as described in RFC 3611, section 4.1
123
- # [ derive ( Debug , Default , PartialEq , Clone ) ]
124
- pub struct LossRLEReportBlock ( pub RleReportBlock ) ;
117
+ /// make sure to set is_loss_rle = true
118
+ pub type LossRLEReportBlock = RLEReportBlock ;
125
119
126
- impl fmt:: Display for LossRLEReportBlock {
127
- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
128
- write ! ( f, "{:?}" , self )
120
+ /// DuplicateRLEReportBlock is used to report information about packet
121
+ /// duplication, as described in RFC 3611, section 4.1
122
+ /// make sure to set is_loss_rle = false
123
+ pub type DuplicateRLEReportBlock = RLEReportBlock ;
124
+
125
+ impl RLEReportBlock {
126
+ pub fn xr_header ( & self ) -> XRHeader {
127
+ XRHeader {
128
+ block_type : if self . is_loss_rle {
129
+ BlockType :: LossRLE
130
+ } else {
131
+ BlockType :: DuplicateRLE
132
+ } ,
133
+ type_specific : self . t & 0x0F ,
134
+ block_length : ( self . raw_size ( ) / 4 - 1 ) as u16 ,
135
+ }
129
136
}
130
137
}
131
138
132
- impl ReportBlock for LossRLEReportBlock {
133
- /// destination_ssrc returns an array of ssrc values that this report block refers to.
134
- fn destination_ssrc ( & self ) -> Vec < u32 > {
135
- vec ! [ self . 0 . ssrc]
139
+ impl fmt:: Display for RLEReportBlock {
140
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
141
+ write ! ( f, "{:?}" , self )
136
142
}
143
+ }
137
144
138
- fn setup_block_header ( & mut self ) {
139
- self . 0 . xr_header . block_type = ReportBlockType :: LossRLE ;
140
- self . 0 . xr_header . type_specific = self . 0 . t & 0x0F ;
141
- self . 0 . xr_header . block_length = ( self . 0 . raw_size ( ) / 4 - 1 ) as u16 ;
145
+ impl Packet for RLEReportBlock {
146
+ fn header ( & self ) -> Header {
147
+ Header :: default ( )
142
148
}
143
149
144
- fn unpack_block_header ( & mut self ) {
145
- self . 0 . t = ( self . 0 . xr_header . type_specific ) & 0x0F ;
150
+ /// destination_ssrc returns an array of ssrc values that this report block refers to.
151
+ fn destination_ssrc ( & self ) -> Vec < u32 > {
152
+ vec ! [ self . ssrc]
146
153
}
147
154
148
155
fn raw_size ( & self ) -> usize {
149
- self . 0 . raw_size ( )
156
+ XR_HEADER_LENGTH + RLE_REPORT_BLOCK_MIN_LENGTH as usize + self . chunks . len ( ) * 2
150
157
}
151
158
152
159
fn as_any ( & self ) -> & ( dyn Any + Send + Sync ) {
153
160
self
154
161
}
155
- fn equal ( & self , other : & ( dyn ReportBlock + Send + Sync ) ) -> bool {
162
+ fn equal ( & self , other : & ( dyn Packet + Send + Sync ) ) -> bool {
156
163
other
157
164
. as_any ( )
158
- . downcast_ref :: < LossRLEReportBlock > ( )
165
+ . downcast_ref :: < RLEReportBlock > ( )
159
166
. map_or ( false , |a| self == a)
160
167
}
161
- fn cloned ( & self ) -> Box < dyn ReportBlock + Send + Sync > {
168
+ fn cloned ( & self ) -> Box < dyn Packet + Send + Sync > {
162
169
Box :: new ( self . clone ( ) )
163
170
}
164
171
}
165
172
166
- /// DuplicateRLEReportBlock is used to report information about packet
167
- /// duplication, as described in RFC 3611, section 4.1
168
- #[ derive( Debug , Default , PartialEq , Clone ) ]
169
- pub struct DuplicateRLEReportBlock ( pub RleReportBlock ) ;
170
-
171
- impl fmt:: Display for DuplicateRLEReportBlock {
172
- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
173
- write ! ( f, "{:?}" , self )
173
+ impl MarshalSize for RLEReportBlock {
174
+ fn marshal_size ( & self ) -> usize {
175
+ self . raw_size ( )
174
176
}
175
177
}
176
178
177
- impl ReportBlock for DuplicateRLEReportBlock {
178
- /// destination_ssrc returns an array of ssrc values that this report block refers to.
179
- fn destination_ssrc ( & self ) -> Vec < u32 > {
180
- vec ! [ self . 0 . ssrc]
181
- }
179
+ impl Marshal for RLEReportBlock {
180
+ /// marshal_to encodes the RleReportBlock in binary
181
+ fn marshal_to ( & self , mut buf : & mut [ u8 ] ) -> Result < usize > {
182
+ if buf. remaining_mut ( ) < self . marshal_size ( ) {
183
+ return Err ( error:: Error :: BufferTooShort . into ( ) ) ;
184
+ }
182
185
183
- fn setup_block_header ( & mut self ) {
184
- self . 0 . xr_header . block_type = ReportBlockType :: DuplicateRLE ;
185
- self . 0 . xr_header . type_specific = self . 0 . t & 0x0F ;
186
- self . 0 . xr_header . block_length = ( self . 0 . raw_size ( ) / 4 - 1 ) as u16 ;
187
- }
186
+ let h = self . xr_header ( ) ;
187
+ let n = h. marshal_to ( buf) ?;
188
+ buf = & mut buf[ n..] ;
188
189
189
- fn unpack_block_header ( & mut self ) {
190
- self . 0 . t = ( self . 0 . xr_header . type_specific ) & 0x0F ;
191
- }
190
+ buf. put_u8 ( self . t ) ;
191
+ buf. put_u32 ( self . ssrc ) ;
192
+ buf. put_u16 ( self . begin_seq ) ;
193
+ buf. put_u16 ( self . end_seq ) ;
194
+ for chunk in & self . chunks {
195
+ buf. put_u16 ( chunk. 0 ) ;
196
+ }
192
197
193
- fn raw_size ( & self ) -> usize {
194
- self . 0 . raw_size ( )
198
+ Ok ( self . marshal_size ( ) )
195
199
}
200
+ }
196
201
197
- fn as_any ( & self ) -> & ( dyn Any + Send + Sync ) {
198
- self
199
- }
200
- fn equal ( & self , other : & ( dyn ReportBlock + Send + Sync ) ) -> bool {
201
- other
202
- . as_any ( )
203
- . downcast_ref :: < DuplicateRLEReportBlock > ( )
204
- . map_or ( false , |a| self == a)
205
- }
206
- fn cloned ( & self ) -> Box < dyn ReportBlock + Send + Sync > {
207
- Box :: new ( self . clone ( ) )
202
+ impl Unmarshal for RLEReportBlock {
203
+ /// Unmarshal decodes the RleReportBlock from binary
204
+ fn unmarshal < B > ( raw_packet : & mut B ) -> Result < Self >
205
+ where
206
+ Self : Sized ,
207
+ B : Buf ,
208
+ {
209
+ if raw_packet. remaining ( ) < XR_HEADER_LENGTH {
210
+ return Err ( error:: Error :: PacketTooShort . into ( ) ) ;
211
+ }
212
+
213
+ let xr_header = XRHeader :: unmarshal ( raw_packet) ?;
214
+
215
+ if xr_header. block_length < RLE_REPORT_BLOCK_MIN_LENGTH
216
+ || ( xr_header. block_length - RLE_REPORT_BLOCK_MIN_LENGTH ) % 2 != 0
217
+ || raw_packet. remaining ( ) < xr_header. block_length as usize
218
+ {
219
+ return Err ( error:: Error :: PacketTooShort . into ( ) ) ;
220
+ }
221
+
222
+ let is_loss_rle = xr_header. block_type == BlockType :: LossRLE ;
223
+ let t = raw_packet. get_u8 ( ) ;
224
+ let ssrc = raw_packet. get_u32 ( ) ;
225
+ let begin_seq = raw_packet. get_u16 ( ) ;
226
+ let end_seq = raw_packet. get_u16 ( ) ;
227
+
228
+ let remaining = xr_header. block_length - RLE_REPORT_BLOCK_MIN_LENGTH ;
229
+ let mut chunks = vec ! [ ] ;
230
+ for _ in 0 ..remaining / 2 {
231
+ chunks. push ( Chunk ( raw_packet. get_u16 ( ) ) ) ;
232
+ }
233
+
234
+ Ok ( RLEReportBlock {
235
+ is_loss_rle,
236
+ t,
237
+ ssrc,
238
+ begin_seq,
239
+ end_seq,
240
+ chunks,
241
+ } )
208
242
}
209
243
}
0 commit comments