Skip to content
File

Blob: firmware/vendor/sctp-proto/src/param/param_outgoing_reset_request.rs

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