cat_dev/fsemul/pcfs/sata/proto/
ping.rs1use crate::errors::NetworkParseError;
8use bytes::{Buf, BufMut, Bytes, BytesMut};
9use valuable::{Fields, NamedField, NamedValues, StructDef, Structable, Valuable, Value, Visit};
10
11#[derive(Copy, Clone, Debug, PartialEq, Eq, Valuable)]
13pub struct SataPingPacketBody;
14
15impl SataPingPacketBody {
16 #[must_use]
17 pub const fn new() -> Self {
18 Self
19 }
20}
21
22impl Default for SataPingPacketBody {
23 fn default() -> Self {
24 Self
25 }
26}
27
28impl TryFrom<Bytes> for SataPingPacketBody {
29 type Error = NetworkParseError;
30
31 fn try_from(value: Bytes) -> Result<Self, Self::Error> {
32 if !value.is_empty() {
33 return Err(NetworkParseError::UnexpectedTrailer(
34 "SataPingPacketBody",
35 value,
36 ));
37 }
38
39 Ok(Self)
40 }
41}
42
43impl From<&SataPingPacketBody> for Bytes {
44 fn from(_: &SataPingPacketBody) -> Self {
45 Bytes::new()
46 }
47}
48
49impl From<SataPingPacketBody> for Bytes {
50 fn from(_: SataPingPacketBody) -> Self {
51 Bytes::new()
52 }
53}
54
55#[derive(Clone, Debug, PartialEq, Eq)]
57pub struct SataPongBody {
58 fast_file_io_enabled: bool,
60 combined_send_recv_enabled: bool,
62}
63
64impl SataPongBody {
65 #[must_use]
66 pub const fn new(ffio_enabled: bool, csr_enabled: bool) -> Self {
67 Self {
68 fast_file_io_enabled: ffio_enabled,
69 combined_send_recv_enabled: csr_enabled,
70 }
71 }
72
73 #[must_use]
74 pub const fn ffio_enabled(&self) -> bool {
75 self.fast_file_io_enabled
76 }
77
78 pub const fn set_ffio_enabled(&mut self, enabled: bool) {
79 self.fast_file_io_enabled = enabled;
80 }
81
82 #[must_use]
83 pub const fn combined_send_recv_enabled(&self) -> bool {
84 self.combined_send_recv_enabled
85 }
86
87 pub const fn set_combined_send_recv_enabled(&mut self, enabled: bool) {
88 self.combined_send_recv_enabled = enabled;
89 }
90}
91
92impl From<&SataPongBody> for Bytes {
93 fn from(value: &SataPongBody) -> Self {
94 let mut buff = BytesMut::with_capacity(8);
95
96 buff.put_u32(0x0); buff.put_u32(
98 match (value.fast_file_io_enabled, value.combined_send_recv_enabled) {
99 (true, true) => 0xCAFE_0003,
100 (true, false) => 0xCAFE_0001,
101 (false, true) => 0xCAFE_0002,
102 (false, false) => 0x0000_0000,
103 },
104 );
105
106 buff.freeze()
107 }
108}
109
110impl From<SataPongBody> for Bytes {
111 fn from(value: SataPongBody) -> Self {
112 Self::from(&value)
113 }
114}
115
116impl TryFrom<Bytes> for SataPongBody {
117 type Error = NetworkParseError;
118
119 fn try_from(mut value: Bytes) -> Result<Self, Self::Error> {
120 if value.len() < 0x8 {
121 return Err(NetworkParseError::FieldNotLongEnough(
122 "SataPongBody",
123 "Body",
124 0x8,
125 value.len(),
126 value,
127 ));
128 }
129 if value.len() > 0x8 {
130 return Err(NetworkParseError::UnexpectedTrailer(
131 "SataPongBody",
132 value.slice(0x8..),
133 ));
134 }
135
136 let rc = value.get_u32();
138 if rc != 0 {
139 return Err(NetworkParseError::ErrorCode(rc));
140 }
141 let flags = value.get_u32();
142
143 Ok(Self {
144 fast_file_io_enabled: flags == 0xCAFE_0003 || flags == 0xCAFE_0001,
145 combined_send_recv_enabled: flags == 0xCAFE_0003 || flags == 0xCAFE_0002,
146 })
147 }
148}
149
150const SATA_PONG_BODY_FIELDS: &[NamedField<'static>] = &[
151 NamedField::new("fast_file_io_enabled"),
152 NamedField::new("combined_send_recv_enabled"),
153];
154
155impl Structable for SataPongBody {
156 fn definition(&self) -> StructDef<'_> {
157 StructDef::new_static("SataPongBody", Fields::Named(SATA_PONG_BODY_FIELDS))
158 }
159}
160
161impl Valuable for SataPongBody {
162 fn as_value(&self) -> Value<'_> {
163 Value::Structable(self)
164 }
165
166 fn visit(&self, visitor: &mut dyn Visit) {
167 visitor.visit_named_fields(&NamedValues::new(
168 SATA_PONG_BODY_FIELDS,
169 &[
170 Valuable::as_value(&self.fast_file_io_enabled),
171 Valuable::as_value(&self.combined_send_recv_enabled),
172 ],
173 ));
174 }
175}