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