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