1 use super::{param_header::*, param_type::*, *};
2 
3 use bytes::{Buf, BufMut, Bytes, BytesMut};
4 use std::fmt;
5 
6 #[derive(Default, Debug, Copy, Clone, PartialEq)]
7 #[repr(C)]
8 pub(crate) enum ReconfigResult {
9     SuccessNop = 0,
10     SuccessPerformed = 1,
11     Denied = 2,
12     ErrorWrongSsn = 3,
13     ErrorRequestAlreadyInProgress = 4,
14     ErrorBadSequenceNumber = 5,
15     InProgress = 6,
16     #[default]
17     Unknown,
18 }
19 
20 impl fmt::Display for ReconfigResult {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result21     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22         let s = match *self {
23             ReconfigResult::SuccessNop => "0: Success - Nothing to do",
24             ReconfigResult::SuccessPerformed => "1: Success - Performed",
25             ReconfigResult::Denied => "2: Denied",
26             ReconfigResult::ErrorWrongSsn => "3: Error - Wrong SSN",
27             ReconfigResult::ErrorRequestAlreadyInProgress => {
28                 "4: Error - Request already in progress"
29             }
30             ReconfigResult::ErrorBadSequenceNumber => "5: Error - Bad Sequence Number",
31             ReconfigResult::InProgress => "6: In progress",
32             _ => "Unknown ReconfigResult",
33         };
34         write!(f, "{s}")
35     }
36 }
37 
38 impl From<u32> for ReconfigResult {
from(v: u32) -> ReconfigResult39     fn from(v: u32) -> ReconfigResult {
40         match v {
41             0 => ReconfigResult::SuccessNop,
42             1 => ReconfigResult::SuccessPerformed,
43             2 => ReconfigResult::Denied,
44             3 => ReconfigResult::ErrorWrongSsn,
45             4 => ReconfigResult::ErrorRequestAlreadyInProgress,
46             5 => ReconfigResult::ErrorBadSequenceNumber,
47             6 => ReconfigResult::InProgress,
48             _ => ReconfigResult::Unknown,
49         }
50     }
51 }
52 
53 ///This parameter is used by the receiver of a Re-configuration Request
54 ///Parameter to respond to the request.
55 ///
56 ///0                   1                   2                   3
57 ///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
58 ///+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59 ///|     Parameter Type = 16       |      Parameter Length         |
60 ///+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61 ///|         Re-configuration Response Sequence Number             |
62 ///+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
63 ///|                            Result                             |
64 ///+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
65 ///|                   Sender's Next TSN (optional)                |
66 ///+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
67 ///|                  Receiver's Next TSN (optional)               |
68 ///+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
69 #[derive(Default, Debug, Clone, PartialEq)]
70 pub(crate) struct ParamReconfigResponse {
71     /// This value is copied from the request parameter and is used by the
72     /// receiver of the Re-configuration Response Parameter to tie the
73     /// response to the request.
74     pub(crate) reconfig_response_sequence_number: u32,
75     /// This value describes the result of the processing of the request.
76     pub(crate) result: ReconfigResult,
77 }
78 
79 impl fmt::Display for ParamReconfigResponse {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result80     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81         write!(
82             f,
83             "{} {} {}",
84             self.header(),
85             self.reconfig_response_sequence_number,
86             self.result
87         )
88     }
89 }
90 
91 impl Param for ParamReconfigResponse {
header(&self) -> ParamHeader92     fn header(&self) -> ParamHeader {
93         ParamHeader {
94             typ: ParamType::ReconfigResp,
95             value_length: self.value_length() as u16,
96         }
97     }
98 
unmarshal(raw: &Bytes) -> Result<Self>99     fn unmarshal(raw: &Bytes) -> Result<Self> {
100         let header = ParamHeader::unmarshal(raw)?;
101 
102         // validity of value_length is checked in ParamHeader::unmarshal
103         if header.value_length < 8 {
104             return Err(Error::ErrReconfigRespParamTooShort);
105         }
106 
107         let reader =
108             &mut raw.slice(PARAM_HEADER_LENGTH..PARAM_HEADER_LENGTH + header.value_length());
109 
110         let reconfig_response_sequence_number = reader.get_u32();
111         let result = reader.get_u32().into();
112 
113         Ok(ParamReconfigResponse {
114             reconfig_response_sequence_number,
115             result,
116         })
117     }
118 
marshal_to(&self, buf: &mut BytesMut) -> Result<usize>119     fn marshal_to(&self, buf: &mut BytesMut) -> Result<usize> {
120         self.header().marshal_to(buf)?;
121         buf.put_u32(self.reconfig_response_sequence_number);
122         buf.put_u32(self.result as u32);
123         Ok(buf.len())
124     }
125 
value_length(&self) -> usize126     fn value_length(&self) -> usize {
127         8
128     }
129 
clone_to(&self) -> Box<dyn Param + Send + Sync>130     fn clone_to(&self) -> Box<dyn Param + Send + Sync> {
131         Box::new(self.clone())
132     }
133 
as_any(&self) -> &(dyn Any + Send + Sync)134     fn as_any(&self) -> &(dyn Any + Send + Sync) {
135         self
136     }
137 }
138