xref: /openbmc/libpldm/src/dsp/file.c (revision c6837f00be70b3aac2c654d5e399f57a652452ae)
1 /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
2 #include "dsp/base.h"
3 #include "msgbuf.h"
4 
5 #include <libpldm/base.h>
6 #include <libpldm/file.h>
7 
8 #include <assert.h>
9 #include <errno.h>
10 #include <stdbool.h>
11 #include <stdint.h>
12 #include <string.h>
13 #include <stdlib.h>
14 
15 LIBPLDM_ABI_STABLE
encode_pldm_file_df_open_req(uint8_t instance_id,const struct pldm_file_df_open_req * req,struct pldm_msg * msg,size_t * payload_length)16 int encode_pldm_file_df_open_req(uint8_t instance_id,
17 				 const struct pldm_file_df_open_req *req,
18 				 struct pldm_msg *msg, size_t *payload_length)
19 {
20 	PLDM_MSGBUF_RW_DEFINE_P(buf);
21 	int rc;
22 
23 	if (req == NULL || msg == NULL) {
24 		return -EINVAL;
25 	}
26 
27 	struct pldm_header_info header = { 0 };
28 	header.instance = instance_id;
29 	header.msg_type = PLDM_REQUEST;
30 	header.pldm_type = PLDM_FILE;
31 	header.command = PLDM_FILE_CMD_DF_OPEN;
32 
33 	rc = pack_pldm_header_errno(&header, &(msg->hdr));
34 	if (rc) {
35 		return rc;
36 	}
37 
38 	rc = pldm_msgbuf_init_errno(buf, PLDM_DF_OPEN_REQ_BYTES, msg->payload,
39 				    *payload_length);
40 	if (rc) {
41 		return rc;
42 	}
43 
44 	pldm_msgbuf_insert(buf, req->file_identifier);
45 	pldm_msgbuf_insert(buf, req->file_attribute.value);
46 
47 	return pldm_msgbuf_complete_used(buf, *payload_length, payload_length);
48 }
49 
50 LIBPLDM_ABI_TESTING
decode_pldm_file_df_open_req(const struct pldm_msg * msg,size_t payload_length,struct pldm_file_df_open_req * req)51 int decode_pldm_file_df_open_req(const struct pldm_msg *msg,
52 				 size_t payload_length,
53 				 struct pldm_file_df_open_req *req)
54 {
55 	PLDM_MSGBUF_RO_DEFINE_P(buf);
56 	int rc;
57 
58 	if (!msg || !req) {
59 		return -EINVAL;
60 	}
61 
62 	rc = pldm_msgbuf_init_errno(buf, PLDM_DF_OPEN_REQ_BYTES, msg->payload,
63 				    payload_length);
64 	if (rc) {
65 		return rc;
66 	}
67 
68 	pldm_msgbuf_extract(buf, req->file_identifier);
69 	pldm_msgbuf_extract(buf, req->file_attribute.value);
70 
71 	return pldm_msgbuf_complete_consumed(buf);
72 }
73 
74 LIBPLDM_ABI_TESTING
encode_pldm_file_df_open_resp(uint8_t instance_id,const struct pldm_file_df_open_resp * resp,struct pldm_msg * msg,size_t * payload_length)75 int encode_pldm_file_df_open_resp(uint8_t instance_id,
76 				  const struct pldm_file_df_open_resp *resp,
77 				  struct pldm_msg *msg, size_t *payload_length)
78 {
79 	PLDM_MSGBUF_RW_DEFINE_P(buf);
80 	int rc;
81 
82 	if (!msg || !resp) {
83 		return -EINVAL;
84 	}
85 
86 	struct pldm_header_info header = { 0 };
87 	header.instance = instance_id;
88 	header.msg_type = PLDM_RESPONSE;
89 	header.pldm_type = PLDM_FILE;
90 	header.command = PLDM_FILE_CMD_DF_OPEN;
91 
92 	rc = pack_pldm_header_errno(&header, &(msg->hdr));
93 	if (rc) {
94 		return rc;
95 	}
96 
97 	rc = pldm_msgbuf_init_errno(buf, PLDM_DF_OPEN_RESP_BYTES, msg->payload,
98 				    *payload_length);
99 	if (rc) {
100 		return rc;
101 	}
102 
103 	pldm_msgbuf_insert(buf, resp->completion_code);
104 	if (resp->completion_code == PLDM_SUCCESS) {
105 		pldm_msgbuf_insert(buf, resp->file_descriptor);
106 	}
107 
108 	return pldm_msgbuf_complete_used(buf, *payload_length, payload_length);
109 }
110 
111 LIBPLDM_ABI_STABLE
decode_pldm_file_df_open_resp(const struct pldm_msg * msg,size_t payload_length,struct pldm_file_df_open_resp * resp)112 int decode_pldm_file_df_open_resp(const struct pldm_msg *msg,
113 				  size_t payload_length,
114 				  struct pldm_file_df_open_resp *resp)
115 {
116 	PLDM_MSGBUF_RO_DEFINE_P(buf);
117 	int rc;
118 
119 	if (!msg || !resp) {
120 		return -EINVAL;
121 	}
122 
123 	rc = pldm_msg_has_error(msg, payload_length);
124 	if (rc) {
125 		resp->completion_code = rc;
126 		return 0;
127 	}
128 
129 	rc = pldm_msgbuf_init_errno(buf, PLDM_DF_OPEN_RESP_BYTES, msg->payload,
130 				    payload_length);
131 	if (rc) {
132 		return rc;
133 	}
134 
135 	pldm_msgbuf_extract(buf, resp->completion_code);
136 	if (resp->completion_code != PLDM_SUCCESS) {
137 		// Return the CC directly without decoding the rest of the payload
138 		return pldm_msgbuf_complete(buf);
139 	}
140 
141 	pldm_msgbuf_extract(buf, resp->file_descriptor);
142 
143 	return pldm_msgbuf_complete_consumed(buf);
144 }
145 
146 LIBPLDM_ABI_STABLE
encode_pldm_file_df_close_req(uint8_t instance_id,const struct pldm_file_df_close_req * req,struct pldm_msg * msg,size_t * payload_length)147 int encode_pldm_file_df_close_req(uint8_t instance_id,
148 				  const struct pldm_file_df_close_req *req,
149 				  struct pldm_msg *msg, size_t *payload_length)
150 {
151 	PLDM_MSGBUF_RW_DEFINE_P(buf);
152 	int rc;
153 
154 	if (!req || !msg) {
155 		return -EINVAL;
156 	}
157 
158 	struct pldm_header_info header = { 0 };
159 	header.instance = instance_id;
160 	header.msg_type = PLDM_REQUEST;
161 	header.pldm_type = PLDM_FILE;
162 	header.command = PLDM_FILE_CMD_DF_CLOSE;
163 
164 	rc = pack_pldm_header_errno(&header, &(msg->hdr));
165 	if (rc) {
166 		return rc;
167 	}
168 
169 	rc = pldm_msgbuf_init_errno(buf, PLDM_DF_CLOSE_REQ_BYTES, msg->payload,
170 				    *payload_length);
171 	if (rc) {
172 		return rc;
173 	}
174 
175 	pldm_msgbuf_insert(buf, req->file_descriptor);
176 	pldm_msgbuf_insert(buf, req->df_close_options.value);
177 
178 	return pldm_msgbuf_complete_used(buf, *payload_length, payload_length);
179 }
180 
181 LIBPLDM_ABI_TESTING
decode_pldm_file_df_close_req(const struct pldm_msg * msg,size_t payload_length,struct pldm_file_df_close_req * req)182 int decode_pldm_file_df_close_req(const struct pldm_msg *msg,
183 				  size_t payload_length,
184 				  struct pldm_file_df_close_req *req)
185 {
186 	PLDM_MSGBUF_RO_DEFINE_P(buf);
187 	int rc;
188 
189 	if (!msg || !req) {
190 		return -EINVAL;
191 	}
192 
193 	rc = pldm_msgbuf_init_errno(buf, PLDM_DF_CLOSE_REQ_BYTES, msg->payload,
194 				    payload_length);
195 	if (rc) {
196 		return rc;
197 	}
198 
199 	pldm_msgbuf_extract(buf, req->file_descriptor);
200 	pldm_msgbuf_extract(buf, req->df_close_options.value);
201 
202 	return pldm_msgbuf_complete_consumed(buf);
203 }
204 
205 LIBPLDM_ABI_TESTING
encode_pldm_file_df_close_resp(uint8_t instance_id,const struct pldm_file_df_close_resp * resp,struct pldm_msg * msg,size_t * payload_length)206 int encode_pldm_file_df_close_resp(uint8_t instance_id,
207 				   const struct pldm_file_df_close_resp *resp,
208 				   struct pldm_msg *msg, size_t *payload_length)
209 {
210 	PLDM_MSGBUF_RW_DEFINE_P(buf);
211 	int rc;
212 
213 	if (!msg || !resp) {
214 		return -EINVAL;
215 	}
216 
217 	struct pldm_header_info header = { 0 };
218 	header.instance = instance_id;
219 	header.msg_type = PLDM_RESPONSE;
220 	header.pldm_type = PLDM_FILE;
221 	header.command = PLDM_FILE_CMD_DF_CLOSE;
222 
223 	rc = pack_pldm_header_errno(&header, &(msg->hdr));
224 	if (rc) {
225 		return rc;
226 	}
227 
228 	rc = pldm_msgbuf_init_errno(buf, PLDM_DF_CLOSE_RESP_BYTES, msg->payload,
229 				    *payload_length);
230 	if (rc) {
231 		return rc;
232 	}
233 
234 	pldm_msgbuf_insert(buf, resp->completion_code);
235 
236 	return pldm_msgbuf_complete_used(buf, *payload_length, payload_length);
237 }
238 
239 LIBPLDM_ABI_STABLE
decode_pldm_file_df_close_resp(const struct pldm_msg * msg,size_t payload_length,struct pldm_file_df_close_resp * resp)240 int decode_pldm_file_df_close_resp(const struct pldm_msg *msg,
241 				   size_t payload_length,
242 				   struct pldm_file_df_close_resp *resp)
243 {
244 	if (!msg || !resp) {
245 		return -EINVAL;
246 	}
247 
248 	resp->completion_code = pldm_msg_has_error(msg, payload_length);
249 
250 	return 0;
251 }
252 
253 LIBPLDM_ABI_STABLE
encode_pldm_file_df_heartbeat_req(uint8_t instance_id,const struct pldm_file_df_heartbeat_req * req,struct pldm_msg * msg,size_t * payload_length)254 int encode_pldm_file_df_heartbeat_req(
255 	uint8_t instance_id, const struct pldm_file_df_heartbeat_req *req,
256 	struct pldm_msg *msg, size_t *payload_length)
257 {
258 	PLDM_MSGBUF_RW_DEFINE_P(buf);
259 	int rc;
260 
261 	if (!req || !msg) {
262 		return -EINVAL;
263 	}
264 
265 	struct pldm_header_info header = { 0 };
266 	header.instance = instance_id;
267 	header.msg_type = PLDM_REQUEST;
268 	header.pldm_type = PLDM_FILE;
269 	header.command = PLDM_FILE_CMD_DF_HEARTBEAT;
270 
271 	rc = pack_pldm_header_errno(&header, &(msg->hdr));
272 	if (rc) {
273 		return rc;
274 	}
275 
276 	rc = pldm_msgbuf_init_errno(buf, PLDM_DF_HEARTBEAT_REQ_BYTES,
277 				    msg->payload, *payload_length);
278 	if (rc) {
279 		return rc;
280 	}
281 
282 	pldm_msgbuf_insert(buf, req->file_descriptor);
283 	pldm_msgbuf_insert(buf, req->requester_max_interval);
284 
285 	return pldm_msgbuf_complete_used(buf, *payload_length, payload_length);
286 }
287 
288 LIBPLDM_ABI_STABLE
decode_pldm_file_df_heartbeat_resp(const struct pldm_msg * msg,size_t payload_length,struct pldm_file_df_heartbeat_resp * resp)289 int decode_pldm_file_df_heartbeat_resp(const struct pldm_msg *msg,
290 				       size_t payload_length,
291 				       struct pldm_file_df_heartbeat_resp *resp)
292 {
293 	PLDM_MSGBUF_RO_DEFINE_P(buf);
294 	int rc;
295 
296 	if (!msg || !resp) {
297 		return -EINVAL;
298 	}
299 
300 	rc = pldm_msg_has_error(msg, payload_length);
301 	if (rc) {
302 		resp->completion_code = rc;
303 		return 0;
304 	}
305 
306 	rc = pldm_msgbuf_init_errno(buf, PLDM_DF_HEARTBEAT_RESP_BYTES,
307 				    msg->payload, payload_length);
308 	if (rc) {
309 		return rc;
310 	}
311 
312 	pldm_msgbuf_extract(buf, resp->completion_code);
313 	pldm_msgbuf_extract(buf, resp->responder_max_interval);
314 
315 	return pldm_msgbuf_complete_consumed(buf);
316 }
317