webrtc_sctp/param/
param_outgoing_reset_request.rs

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