1use crate::base_packet::{
6 MCTPMessageBody, MCTPMessageBodyHeader, MCTPTransportHeader, MessageType,
7};
8use crate::control_packet::CommandCode;
9use crate::smbus_proto::{MCTPSMBusHeader, MCTPSMBusPacket, HDR_VERSION, MCTP_SMBUS_COMMAND_CODE};
10
11pub(crate) trait MCTPHeader {
13 fn len(&self) -> usize;
15
16 fn is_empty(&self) -> bool {
18 self.len() == 0
19 }
20
21 fn to_raw_bytes(&self, buf: &mut [u8]) -> usize;
28}
29
30pub(crate) trait MCTPControlMessageRequest {
32 fn command_code(&self) -> u8;
33
34 fn get_request_data_len(&self) -> usize {
36 match self.command_code().into() {
37 CommandCode::Reserved => 0,
38 CommandCode::SetEndpointID => 2,
39 CommandCode::GetEndpointID => 0,
40 CommandCode::GetEndpointUUID => 0,
41 CommandCode::GetMCTPVersionSupport => 1,
42 CommandCode::GetMessageTypeSupport => 0,
43 CommandCode::GetVendorDefinedMessageSupport => 1,
44 CommandCode::ResolveEndpointID => 1,
45 CommandCode::AllocateEndpointIDs => 3,
46 CommandCode::RoutingInformationUpdate => unimplemented!(),
47 CommandCode::GetRoutingTableEntries => unimplemented!(),
48 CommandCode::PrepareForEndpointDiscovery => unimplemented!(),
49 CommandCode::EndpointDiscovery => unimplemented!(),
50 CommandCode::DiscoveryNotify => unimplemented!(),
51 CommandCode::GetNetworkID => unimplemented!(),
52 CommandCode::QueryHop => unimplemented!(),
53 CommandCode::ResolveUUID => unimplemented!(),
54 CommandCode::QueryRateLimit => unimplemented!(),
55 CommandCode::RequestTXRateLimit => unimplemented!(),
56 CommandCode::UpdateRateLimit => unimplemented!(),
57 CommandCode::QuerySupportedInterfaces => unimplemented!(),
58 CommandCode::Unknown => unimplemented!(),
59 }
60 }
61
62 fn get_response_data_len(&self) -> usize {
65 match self.command_code().into() {
66 CommandCode::Reserved => 0,
67 CommandCode::SetEndpointID => 3,
68 CommandCode::GetEndpointID => 4,
69 CommandCode::GetEndpointUUID => 16,
70 CommandCode::GetMCTPVersionSupport => 5,
71 CommandCode::GetMessageTypeSupport => 0,
72 CommandCode::GetVendorDefinedMessageSupport => 0,
73 CommandCode::ResolveEndpointID => unimplemented!(),
74 CommandCode::AllocateEndpointIDs => 4,
75 CommandCode::RoutingInformationUpdate => 1,
76 CommandCode::GetRoutingTableEntries => unimplemented!(),
77 CommandCode::PrepareForEndpointDiscovery => unimplemented!(),
78 CommandCode::EndpointDiscovery => unimplemented!(),
79 CommandCode::DiscoveryNotify => unimplemented!(),
80 CommandCode::GetNetworkID => unimplemented!(),
81 CommandCode::QueryHop => unimplemented!(),
82 CommandCode::ResolveUUID => unimplemented!(),
83 CommandCode::QueryRateLimit => unimplemented!(),
84 CommandCode::RequestTXRateLimit => unimplemented!(),
85 CommandCode::UpdateRateLimit => unimplemented!(),
86 CommandCode::QuerySupportedInterfaces => unimplemented!(),
87 CommandCode::Unknown => unimplemented!(),
88 }
89 }
90}
91
92pub trait SMBusMCTPRequestResponse {
94 fn get_address(&self) -> u8;
98
99 fn get_eid(&self) -> u8;
103
104 fn set_eid(&self, eid: u8);
108
109 fn generate_transport_header(&self, dest_addr: u8) -> MCTPTransportHeader<[u8; 4]> {
111 let mut base_header: MCTPTransportHeader<[u8; 4]> = MCTPTransportHeader::new(HDR_VERSION);
112 base_header.set_dest_endpoint_id(dest_addr);
113 base_header.set_source_endpoint_id(self.get_address());
114 base_header.set_som(true as u8);
115 base_header.set_eom(true as u8);
116 base_header.set_pkt_seq(0);
117 base_header.set_to(true as u8);
118 base_header.set_msg_tag(0);
119
120 base_header
121 }
122
123 fn generate_smbus_header(&self, dest_addr: u8) -> MCTPSMBusHeader<[u8; 4]> {
125 let mut smbus_header: MCTPSMBusHeader<[u8; 4]> = MCTPSMBusHeader::new();
126 smbus_header.set_dest_read_write(0);
127 smbus_header.set_dest_slave_addr(dest_addr);
128 smbus_header.set_command_code(MCTP_SMBUS_COMMAND_CODE);
129 smbus_header.set_source_slave_addr(self.get_address());
130 smbus_header.set_source_read_write(1);
131
132 smbus_header
133 }
134
135 fn generate_control_packet_bytes(
137 &self,
138 dest_addr: u8,
139 message_header: &Option<&[u8]>,
140 message_data: &[u8],
141 buf: &mut [u8],
142 ) -> Result<usize, ()> {
143 let mut smbus_header = self.generate_smbus_header(dest_addr);
144 let base_header = self.generate_transport_header(dest_addr);
145
146 let header: MCTPMessageBodyHeader<[u8; 1]> =
147 MCTPMessageBodyHeader::new(false, MessageType::MCtpControl);
148
149 let body = MCTPMessageBody::new(&header, *message_header, message_data, None);
150
151 let packet = MCTPSMBusPacket::new(&mut smbus_header, &base_header, &body);
152
153 Ok(packet.to_raw_bytes(buf))
154 }
155
156 fn generate_pci_msg_packet_bytes(
158 &self,
159 dest_addr: u8,
160 message_header: &Option<&[u8]>,
161 message_data: &[u8],
162 buf: &mut [u8],
163 ) -> Result<usize, ()> {
164 let mut smbus_header = self.generate_smbus_header(dest_addr);
165 let base_header = self.generate_transport_header(dest_addr);
166
167 let header: MCTPMessageBodyHeader<[u8; 1]> =
168 MCTPMessageBodyHeader::new(false, MessageType::VendorDefinedPCI);
169
170 let body = MCTPMessageBody::new(&header, *message_header, message_data, None);
171
172 let packet = MCTPSMBusPacket::new(&mut smbus_header, &base_header, &body);
173
174 Ok(packet.to_raw_bytes(buf))
175 }
176
177 fn generate_spdm_msg_packet_bytes(
179 &self,
180 dest_addr: u8,
181 message_type: MessageType,
182 message_header: &Option<&[u8]>,
183 message_data: &[u8],
184 buf: &mut [u8],
185 ) -> Result<usize, ()> {
186 let mut smbus_header = self.generate_smbus_header(dest_addr);
187 let base_header = self.generate_transport_header(dest_addr);
188
189 let header: MCTPMessageBodyHeader<[u8; 1]> =
190 MCTPMessageBodyHeader::new(false, message_type);
191
192 let body = MCTPMessageBody::new(&header, *message_header, message_data, None);
193
194 let packet = MCTPSMBusPacket::new(&mut smbus_header, &base_header, &body);
195
196 Ok(packet.to_raw_bytes(buf))
197 }
198
199 fn generate_iana_msg_packet_bytes(
201 &self,
202 dest_addr: u8,
203 message_header: &Option<&[u8]>,
204 message_data: &[u8],
205 buf: &mut [u8],
206 ) -> Result<usize, ()> {
207 let mut smbus_header = self.generate_smbus_header(dest_addr);
208 let base_header = self.generate_transport_header(dest_addr);
209
210 let header: MCTPMessageBodyHeader<[u8; 1]> =
211 MCTPMessageBodyHeader::new(false, MessageType::VendorDefinedIANA);
212
213 let body = MCTPMessageBody::new(&header, *message_header, message_data, None);
214
215 let packet = MCTPSMBusPacket::new(&mut smbus_header, &base_header, &body);
216
217 Ok(packet.to_raw_bytes(buf))
218 }
219}