1 use super::{param_header::*, param_type::*, *};
2 
3 use bytes::{Buf, BufMut, Bytes, BytesMut};
4 
5 pub(crate) const PARAM_OUTGOING_RESET_REQUEST_STREAM_IDENTIFIERS_OFFSET: usize = 12;
6 
7 ///This parameter is used by the sender to request the reset of some or
8 ///all outgoing streams.
9 /// 0                   1                   2                   3
10 /// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
11 ///+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
12 ///|     Parameter Type = 13       | Parameter Length = 16 + 2 * N |
13 ///+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
14 ///|           Re-configuration Request Sequence Number            |
15 ///+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16 ///|           Re-configuration Response Sequence Number           |
17 ///+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
18 ///|                Sender's Last Assigned TSN                     |
19 ///+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
20 ///|  Stream Number 1 (optional)   |    Stream Number 2 (optional) |
21 ///+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
22 ///|                            ......                             |
23 ///+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24 ///|  Stream Number N-1 (optional) |    Stream Number N (optional) |
25 ///+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
26 #[derive(Default, Debug, Clone, PartialEq)]
27 pub(crate) struct ParamOutgoingResetRequest {
28     /// reconfig_request_sequence_number is used to identify the request.  It is a monotonically
29     /// increasing number that is initialized to the same value as the
30     /// initial TSN.  It is increased by 1 whenever sending a new Re-
31     /// configuration Request Parameter.
32     pub(crate) reconfig_request_sequence_number: u32,
33     /// When this Outgoing SSN Reset Request Parameter is sent in response
34     /// to an Incoming SSN Reset Request Parameter, this parameter is also
35     /// an implicit response to the incoming request.  This field then
36     /// holds the Re-configuration Request Sequence Number of the incoming
37     /// request.  In other cases, it holds the next expected
38     /// Re-configuration Request Sequence Number minus 1.
39     pub(crate) reconfig_response_sequence_number: u32,
40     /// This value holds the next TSN minus 1 -- in other words, the last
41     /// TSN that this sender assigned.
42     pub(crate) sender_last_tsn: u32,
43     /// This optional field, if included, is used to indicate specific
44     /// streams that are to be reset.  If no streams are listed, then all
45     /// streams are to be reset.
46     pub(crate) stream_identifiers: Vec<u16>,
47 }
48 
49 impl fmt::Display for ParamOutgoingResetRequest {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result50     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51         write!(
52             f,
53             "{} {} {} {} {:?}",
54             self.header(),
55             self.reconfig_request_sequence_number,
56             self.reconfig_request_sequence_number,
57             self.reconfig_response_sequence_number,
58             self.stream_identifiers
59         )
60     }
61 }
62 
63 impl Param for ParamOutgoingResetRequest {
header(&self) -> ParamHeader64     fn header(&self) -> ParamHeader {
65         ParamHeader {
66             typ: ParamType::OutSsnResetReq,
67             value_length: self.value_length() as u16,
68         }
69     }
70 
unmarshal(raw: &Bytes) -> Result<Self>71     fn unmarshal(raw: &Bytes) -> Result<Self> {
72         let header = ParamHeader::unmarshal(raw)?;
73 
74         // validity of value_length is checked in ParamHeader::unmarshal
75         if header.value_length() < PARAM_OUTGOING_RESET_REQUEST_STREAM_IDENTIFIERS_OFFSET {
76             return Err(Error::ErrSsnResetRequestParamTooShort);
77         }
78 
79         let reader =
80             &mut raw.slice(PARAM_HEADER_LENGTH..PARAM_HEADER_LENGTH + header.value_length());
81         let reconfig_request_sequence_number = reader.get_u32();
82         let reconfig_response_sequence_number = reader.get_u32();
83         let sender_last_tsn = reader.get_u32();
84 
85         let lim =
86             (header.value_length() - PARAM_OUTGOING_RESET_REQUEST_STREAM_IDENTIFIERS_OFFSET) / 2;
87         let mut stream_identifiers = vec![];
88         for _ in 0..lim {
89             stream_identifiers.push(reader.get_u16());
90         }
91 
92         Ok(ParamOutgoingResetRequest {
93             reconfig_request_sequence_number,
94             reconfig_response_sequence_number,
95             sender_last_tsn,
96             stream_identifiers,
97         })
98     }
99 
marshal_to(&self, buf: &mut BytesMut) -> Result<usize>100     fn marshal_to(&self, buf: &mut BytesMut) -> Result<usize> {
101         self.header().marshal_to(buf)?;
102         buf.put_u32(self.reconfig_request_sequence_number);
103         buf.put_u32(self.reconfig_response_sequence_number);
104         buf.put_u32(self.sender_last_tsn);
105         for sid in &self.stream_identifiers {
106             buf.put_u16(*sid);
107         }
108         Ok(buf.len())
109     }
110 
value_length(&self) -> usize111     fn value_length(&self) -> usize {
112         PARAM_OUTGOING_RESET_REQUEST_STREAM_IDENTIFIERS_OFFSET + self.stream_identifiers.len() * 2
113     }
114 
clone_to(&self) -> Box<dyn Param + Send + Sync>115     fn clone_to(&self) -> Box<dyn Param + Send + Sync> {
116         Box::new(self.clone())
117     }
118 
as_any(&self) -> &(dyn Any + Send + Sync)119     fn as_any(&self) -> &(dyn Any + Send + Sync) {
120         self
121     }
122 }
123