1
1
use super :: * ;
2
2
3
+ const DLRR_REPORT_LENGTH : u16 = 12 ;
4
+
5
+ /// DLRRReport encodes a single report inside a DLRRReportBlock.
6
+ #[ derive( Debug , Default , PartialEq , Clone ) ]
7
+ pub struct DLRRReport {
8
+ pub ssrc : u32 ,
9
+ pub last_rr : u32 ,
10
+ pub dlrr : u32 ,
11
+ }
12
+
13
+ impl fmt:: Display for DLRRReport {
14
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
15
+ write ! ( f, "{:?}" , self )
16
+ }
17
+ }
18
+
3
19
/// DLRRReportBlock encodes a DLRR Report Block as described in
4
20
/// RFC 3611 section 4.5.
5
21
///
@@ -20,7 +36,6 @@ use super::*;
20
36
/// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
21
37
#[ derive( Debug , Default , PartialEq , Clone ) ]
22
38
pub struct DLRRReportBlock {
23
- pub xr_header : XRHeader ,
24
39
pub reports : Vec < DLRRReport > ,
25
40
}
26
41
@@ -30,21 +45,21 @@ impl fmt::Display for DLRRReportBlock {
30
45
}
31
46
}
32
47
33
- /// DLRRReport encodes a single report inside a DLRRReportBlock.
34
- #[ derive( Debug , Default , PartialEq , Clone ) ]
35
- pub struct DLRRReport {
36
- pub ssrc : u32 ,
37
- pub last_rr : u32 ,
38
- pub dlrr : u32 ,
48
+ impl DLRRReportBlock {
49
+ pub fn xr_header ( & self ) -> XRHeader {
50
+ XRHeader {
51
+ block_type : BlockType :: DLRR ,
52
+ type_specific : 0 ,
53
+ block_length : ( self . raw_size ( ) / 4 - 1 ) as u16 ,
54
+ }
55
+ }
39
56
}
40
57
41
- impl fmt :: Display for DLRRReport {
42
- fn fmt ( & self , f : & mut fmt :: Formatter < ' _ > ) -> fmt :: Result {
43
- write ! ( f , "{:?}" , self )
58
+ impl Packet for DLRRReportBlock {
59
+ fn header ( & self ) -> Header {
60
+ Header :: default ( )
44
61
}
45
- }
46
62
47
- impl ReportBlock for DLRRReportBlock {
48
63
/// destination_ssrc returns an array of ssrc values that this report block refers to.
49
64
fn destination_ssrc ( & self ) -> Vec < u32 > {
50
65
let mut ssrc = Vec :: with_capacity ( self . reports . len ( ) ) ;
@@ -54,28 +69,84 @@ impl ReportBlock for DLRRReportBlock {
54
69
ssrc
55
70
}
56
71
57
- fn setup_block_header ( & mut self ) {
58
- self . xr_header . block_type = ReportBlockType :: DLRR ;
59
- self . xr_header . type_specific = 0 ;
60
- self . xr_header . block_length = ( self . raw_size ( ) / 4 - 1 ) as u16 ;
61
- }
62
-
63
- fn unpack_block_header ( & mut self ) { }
64
-
65
72
fn raw_size ( & self ) -> usize {
66
- 4 + self . reports . len ( ) * 4 * 3
73
+ XR_HEADER_LENGTH + self . reports . len ( ) * 4 * 3
67
74
}
68
75
69
76
fn as_any ( & self ) -> & ( dyn Any + Send + Sync ) {
70
77
self
71
78
}
72
- fn equal ( & self , other : & ( dyn ReportBlock + Send + Sync ) ) -> bool {
79
+ fn equal ( & self , other : & ( dyn Packet + Send + Sync ) ) -> bool {
73
80
other
74
81
. as_any ( )
75
82
. downcast_ref :: < DLRRReportBlock > ( )
76
83
. map_or ( false , |a| self == a)
77
84
}
78
- fn cloned ( & self ) -> Box < dyn ReportBlock + Send + Sync > {
85
+ fn cloned ( & self ) -> Box < dyn Packet + Send + Sync > {
79
86
Box :: new ( self . clone ( ) )
80
87
}
81
88
}
89
+
90
+ impl MarshalSize for DLRRReportBlock {
91
+ fn marshal_size ( & self ) -> usize {
92
+ self . raw_size ( )
93
+ }
94
+ }
95
+
96
+ impl Marshal for DLRRReportBlock {
97
+ /// marshal_to encodes the DLRRReportBlock in binary
98
+ fn marshal_to ( & self , mut buf : & mut [ u8 ] ) -> Result < usize > {
99
+ if buf. remaining_mut ( ) < self . raw_size ( ) {
100
+ return Err ( error:: Error :: BufferTooShort . into ( ) ) ;
101
+ }
102
+
103
+ let h = self . xr_header ( ) ;
104
+ let n = h. marshal_to ( buf) ?;
105
+ buf = & mut buf[ n..] ;
106
+
107
+ for rep in & self . reports {
108
+ buf. put_u32 ( rep. ssrc ) ;
109
+ buf. put_u32 ( rep. last_rr ) ;
110
+ buf. put_u32 ( rep. dlrr ) ;
111
+ }
112
+
113
+ Ok ( self . marshal_size ( ) )
114
+ }
115
+ }
116
+
117
+ impl Unmarshal for DLRRReportBlock {
118
+ /// Unmarshal decodes the DLRRReportBlock from binary
119
+ fn unmarshal < B > ( raw_packet : & mut B ) -> Result < Self >
120
+ where
121
+ Self : Sized ,
122
+ B : Buf ,
123
+ {
124
+ if raw_packet. remaining ( ) < XR_HEADER_LENGTH {
125
+ return Err ( error:: Error :: PacketTooShort . into ( ) ) ;
126
+ }
127
+
128
+ let xr_header = XRHeader :: unmarshal ( raw_packet) ?;
129
+
130
+ if xr_header. block_length % DLRR_REPORT_LENGTH != 0
131
+ || raw_packet. remaining ( ) < xr_header. block_length as usize
132
+ {
133
+ return Err ( error:: Error :: PacketTooShort . into ( ) ) ;
134
+ }
135
+
136
+ let mut offset = 0 ;
137
+ let mut reports = vec ! [ ] ;
138
+ while offset < xr_header. block_length {
139
+ let ssrc = raw_packet. get_u32 ( ) ;
140
+ let last_rr = raw_packet. get_u32 ( ) ;
141
+ let dlrr = raw_packet. get_u32 ( ) ;
142
+ reports. push ( DLRRReport {
143
+ ssrc,
144
+ last_rr,
145
+ dlrr,
146
+ } ) ;
147
+ offset += DLRR_REPORT_LENGTH ;
148
+ }
149
+
150
+ Ok ( DLRRReportBlock { reports } )
151
+ }
152
+ }
0 commit comments